package generator import ( "strings" "testing" "github.com/entity-maker/entity-maker/internal/database" ) func TestSanitizePythonIdentifier(t *testing.T) { tests := []struct { name string input string expected string }{ {"starts with digit", "12_HOUR", "_12_HOUR"}, {"starts with letter", "HOUR_12", "HOUR_12"}, {"all digits", "24", "_24"}, {"underscore first", "_12_HOUR", "_12_HOUR"}, {"empty", "", ""}, {"single digit", "1", "_1"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := sanitizePythonIdentifier(tt.input) if result != tt.expected { t.Errorf("sanitizePythonIdentifier(%q) = %q, want %q", tt.input, result, tt.expected) } }) } } func TestGenerateEnum(t *testing.T) { tests := []struct { name string enumTypes map[string]database.EnumType expectError bool checkFunc func(t *testing.T, result string) }{ { name: "simple enum", enumTypes: map[string]database.EnumType{ "status_enum": { TypeName: "status_enum", Values: []string{"OPEN", "CLOSED", "PENDING"}, }, }, expectError: false, checkFunc: func(t *testing.T, result string) { if !strings.Contains(result, "class StatusEnum") { t.Error("Expected class StatusEnum") } if !strings.Contains(result, "OPEN = \"OPEN\"") { t.Error("Expected OPEN = \"OPEN\"") } if !strings.Contains(result, "CLOSED = \"CLOSED\"") { t.Error("Expected CLOSED = \"CLOSED\"") } if !strings.Contains(result, "PENDING = \"PENDING\"") { t.Error("Expected PENDING = \"PENDING\"") } }, }, { name: "enum with spaces and hyphens", enumTypes: map[string]database.EnumType{ "time_format_enum": { TypeName: "time_format_enum", Values: []string{"12-hour", "24-hour"}, }, }, expectError: false, checkFunc: func(t *testing.T, result string) { if !strings.Contains(result, "class TimeFormatEnum") { t.Error("Expected class TimeFormatEnum") } if !strings.Contains(result, "_12_HOUR = \"12-hour\"") { t.Error("Expected _12_HOUR = \"12-hour\" (sanitized)") } if !strings.Contains(result, "_24_HOUR = \"24-hour\"") { t.Error("Expected _24_HOUR = \"24-hour\" (sanitized)") } }, }, { name: "enum with duplicates after normalization", enumTypes: map[string]database.EnumType{ "measurement_enum": { TypeName: "measurement_enum", Values: []string{"international", "INTERNATIONAL", "imperial", "IMPERIAL"}, }, }, expectError: false, checkFunc: func(t *testing.T, result string) { if !strings.Contains(result, "class MeasurementEnum") { t.Error("Expected class MeasurementEnum") } // Should only have one INTERNATIONAL and one IMPERIAL internationalCount := strings.Count(result, "INTERNATIONAL = ") if internationalCount != 1 { t.Errorf("Expected 1 INTERNATIONAL, got %d", internationalCount) } imperialCount := strings.Count(result, "IMPERIAL = ") if imperialCount != 1 { t.Errorf("Expected 1 IMPERIAL, got %d", imperialCount) } }, }, { name: "empty enum", enumTypes: map[string]database.EnumType{ "empty_enum": { TypeName: "empty_enum", Values: []string{}, }, }, expectError: false, checkFunc: func(t *testing.T, result string) { if !strings.Contains(result, "class EmptyEnum") { t.Error("Expected class EmptyEnum") } if !strings.Contains(result, "pass") { t.Error("Expected 'pass' for empty enum") } }, }, { name: "multiple enums", enumTypes: map[string]database.EnumType{ "status_enum": { TypeName: "status_enum", Values: []string{"OPEN", "CLOSED"}, }, "priority_enum": { TypeName: "priority_enum", Values: []string{"HIGH", "LOW"}, }, }, expectError: false, checkFunc: func(t *testing.T, result string) { if !strings.Contains(result, "class StatusEnum") { t.Error("Expected class StatusEnum") } if !strings.Contains(result, "class PriorityEnum") { t.Error("Expected class PriorityEnum") } }, }, { name: "enum with special characters", enumTypes: map[string]database.EnumType{ "special_enum": { TypeName: "special_enum", Values: []string{"IN-PROGRESS", "ON HOLD", "DONE"}, }, }, expectError: false, checkFunc: func(t *testing.T, result string) { if !strings.Contains(result, "IN_PROGRESS = \"IN-PROGRESS\"") { t.Error("Expected IN_PROGRESS = \"IN-PROGRESS\"") } if !strings.Contains(result, "ON_HOLD = \"ON HOLD\"") { t.Error("Expected ON_HOLD = \"ON HOLD\"") } }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ctx := &Context{ TableInfo: &database.TableInfo{ EnumTypes: tt.enumTypes, }, EntityName: "TestEntity", ModuleName: "test_entity", } result, err := GenerateEnum(ctx) if (err != nil) != tt.expectError { t.Errorf("GenerateEnum() error = %v, expectError %v", err, tt.expectError) return } if tt.checkFunc != nil { tt.checkFunc(t, result) } // Check common requirements if !strings.Contains(result, "from enum import StrEnum") { t.Error("Expected import of StrEnum") } if !strings.Contains(result, "from televend_core.databases.enum import EnumMixin") { t.Error("Expected import of EnumMixin") } }) } }