test(pgsql, reflectutil): ✨ add comprehensive test coverage
All checks were successful
All checks were successful
* Introduce tests for PostgreSQL data types and keywords. * Implement tests for reflect utility functions. * Ensure consistency and correctness of type conversions and keyword mappings. * Validate behavior for various edge cases and input types.
This commit is contained in:
238
pkg/inspector/inspector_test.go
Normal file
238
pkg/inspector/inspector_test.go
Normal file
@@ -0,0 +1,238 @@
|
||||
package inspector
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewInspector(t *testing.T) {
|
||||
db := createTestDatabase()
|
||||
config := GetDefaultConfig()
|
||||
|
||||
inspector := NewInspector(db, config)
|
||||
|
||||
if inspector == nil {
|
||||
t.Fatal("NewInspector() returned nil")
|
||||
}
|
||||
|
||||
if inspector.db != db {
|
||||
t.Error("NewInspector() database not set correctly")
|
||||
}
|
||||
|
||||
if inspector.config != config {
|
||||
t.Error("NewInspector() config not set correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspect(t *testing.T) {
|
||||
db := createTestDatabase()
|
||||
config := GetDefaultConfig()
|
||||
|
||||
inspector := NewInspector(db, config)
|
||||
report, err := inspector.Inspect()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Inspect() returned error: %v", err)
|
||||
}
|
||||
|
||||
if report == nil {
|
||||
t.Fatal("Inspect() returned nil report")
|
||||
}
|
||||
|
||||
if report.Database != db.Name {
|
||||
t.Errorf("Inspect() report.Database = %q, want %q", report.Database, db.Name)
|
||||
}
|
||||
|
||||
if report.Summary.TotalRules != len(config.Rules) {
|
||||
t.Errorf("Inspect() TotalRules = %d, want %d", report.Summary.TotalRules, len(config.Rules))
|
||||
}
|
||||
|
||||
if len(report.Violations) == 0 {
|
||||
t.Error("Inspect() returned no violations, expected some results")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectWithDisabledRules(t *testing.T) {
|
||||
db := createTestDatabase()
|
||||
config := GetDefaultConfig()
|
||||
|
||||
// Disable all rules
|
||||
for name := range config.Rules {
|
||||
rule := config.Rules[name]
|
||||
rule.Enabled = "off"
|
||||
config.Rules[name] = rule
|
||||
}
|
||||
|
||||
inspector := NewInspector(db, config)
|
||||
report, err := inspector.Inspect()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Inspect() with disabled rules returned error: %v", err)
|
||||
}
|
||||
|
||||
if report.Summary.RulesChecked != 0 {
|
||||
t.Errorf("Inspect() RulesChecked = %d, want 0 (all disabled)", report.Summary.RulesChecked)
|
||||
}
|
||||
|
||||
if report.Summary.RulesSkipped != len(config.Rules) {
|
||||
t.Errorf("Inspect() RulesSkipped = %d, want %d", report.Summary.RulesSkipped, len(config.Rules))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInspectWithEnforcedRules(t *testing.T) {
|
||||
db := createTestDatabase()
|
||||
config := GetDefaultConfig()
|
||||
|
||||
// Enable only one rule and enforce it
|
||||
for name := range config.Rules {
|
||||
rule := config.Rules[name]
|
||||
rule.Enabled = "off"
|
||||
config.Rules[name] = rule
|
||||
}
|
||||
|
||||
primaryKeyRule := config.Rules["primary_key_naming"]
|
||||
primaryKeyRule.Enabled = "enforce"
|
||||
primaryKeyRule.Pattern = "^id$"
|
||||
config.Rules["primary_key_naming"] = primaryKeyRule
|
||||
|
||||
inspector := NewInspector(db, config)
|
||||
report, err := inspector.Inspect()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Inspect() returned error: %v", err)
|
||||
}
|
||||
|
||||
if report.Summary.RulesChecked != 1 {
|
||||
t.Errorf("Inspect() RulesChecked = %d, want 1", report.Summary.RulesChecked)
|
||||
}
|
||||
|
||||
// All results should be at error level for enforced rules
|
||||
for _, violation := range report.Violations {
|
||||
if violation.Level != "error" {
|
||||
t.Errorf("Enforced rule violation has Level = %q, want \"error\"", violation.Level)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateSummary(t *testing.T) {
|
||||
db := createTestDatabase()
|
||||
config := GetDefaultConfig()
|
||||
inspector := NewInspector(db, config)
|
||||
|
||||
results := []ValidationResult{
|
||||
{RuleName: "rule1", Passed: true, Level: "error"},
|
||||
{RuleName: "rule2", Passed: false, Level: "error"},
|
||||
{RuleName: "rule3", Passed: false, Level: "warning"},
|
||||
{RuleName: "rule4", Passed: true, Level: "warning"},
|
||||
}
|
||||
|
||||
summary := inspector.generateSummary(results)
|
||||
|
||||
if summary.PassedCount != 2 {
|
||||
t.Errorf("generateSummary() PassedCount = %d, want 2", summary.PassedCount)
|
||||
}
|
||||
|
||||
if summary.ErrorCount != 1 {
|
||||
t.Errorf("generateSummary() ErrorCount = %d, want 1", summary.ErrorCount)
|
||||
}
|
||||
|
||||
if summary.WarningCount != 1 {
|
||||
t.Errorf("generateSummary() WarningCount = %d, want 1", summary.WarningCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasErrors(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
report *InspectorReport
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "with errors",
|
||||
report: &InspectorReport{
|
||||
Summary: ReportSummary{
|
||||
ErrorCount: 5,
|
||||
},
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "without errors",
|
||||
report: &InspectorReport{
|
||||
Summary: ReportSummary{
|
||||
ErrorCount: 0,
|
||||
WarningCount: 3,
|
||||
},
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.report.HasErrors(); got != tt.want {
|
||||
t.Errorf("HasErrors() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetValidator(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
functionName string
|
||||
wantExists bool
|
||||
}{
|
||||
{"primary_key_naming", "primary_key_naming", true},
|
||||
{"primary_key_datatype", "primary_key_datatype", true},
|
||||
{"foreign_key_column_naming", "foreign_key_column_naming", true},
|
||||
{"table_regexpr", "table_regexpr", true},
|
||||
{"column_regexpr", "column_regexpr", true},
|
||||
{"reserved_words", "reserved_words", true},
|
||||
{"have_primary_key", "have_primary_key", true},
|
||||
{"orphaned_foreign_key", "orphaned_foreign_key", true},
|
||||
{"circular_dependency", "circular_dependency", true},
|
||||
{"unknown_function", "unknown_function", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, exists := getValidator(tt.functionName)
|
||||
if exists != tt.wantExists {
|
||||
t.Errorf("getValidator(%q) exists = %v, want %v", tt.functionName, exists, tt.wantExists)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateResult(t *testing.T) {
|
||||
result := createResult(
|
||||
"test_rule",
|
||||
true,
|
||||
"Test message",
|
||||
"schema.table.column",
|
||||
map[string]interface{}{
|
||||
"key1": "value1",
|
||||
"key2": 42,
|
||||
},
|
||||
)
|
||||
|
||||
if result.RuleName != "test_rule" {
|
||||
t.Errorf("createResult() RuleName = %q, want \"test_rule\"", result.RuleName)
|
||||
}
|
||||
|
||||
if !result.Passed {
|
||||
t.Error("createResult() Passed = false, want true")
|
||||
}
|
||||
|
||||
if result.Message != "Test message" {
|
||||
t.Errorf("createResult() Message = %q, want \"Test message\"", result.Message)
|
||||
}
|
||||
|
||||
if result.Location != "schema.table.column" {
|
||||
t.Errorf("createResult() Location = %q, want \"schema.table.column\"", result.Location)
|
||||
}
|
||||
|
||||
if len(result.Context) != 2 {
|
||||
t.Errorf("createResult() Context length = %d, want 2", len(result.Context))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user