test(drawdb): add test for converting column types with modifiers
* Implement tests to ensure explicit type modifiers are preserved during conversion. * Validate behavior for varchar, numeric, and custom vector types.
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/pgsql"
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
||||
)
|
||||
|
||||
@@ -784,11 +785,14 @@ func (r *Reader) extractGormTag(tag string) string {
|
||||
// parseTypeWithLength parses a type string and extracts length if present
|
||||
// e.g., "varchar(255)" returns ("varchar", 255)
|
||||
func (r *Reader) parseTypeWithLength(typeStr string) (baseType string, length int) {
|
||||
typeStr = strings.TrimSpace(typeStr)
|
||||
baseType = typeStr
|
||||
|
||||
// Check for type with length: varchar(255), char(10), etc.
|
||||
// Also handle precision/scale: numeric(10,2)
|
||||
if strings.Contains(typeStr, "(") {
|
||||
idx := strings.Index(typeStr, "(")
|
||||
baseType = strings.TrimSpace(typeStr[:idx])
|
||||
rawBaseType := strings.TrimSpace(typeStr[:idx])
|
||||
|
||||
// Extract numbers from parentheses
|
||||
parens := typeStr[idx+1:]
|
||||
@@ -796,14 +800,15 @@ func (r *Reader) parseTypeWithLength(typeStr string) (baseType string, length in
|
||||
parens = parens[:endIdx]
|
||||
}
|
||||
|
||||
// For now, just handle single number (length)
|
||||
if !strings.Contains(parens, ",") {
|
||||
// Only treat as "length" for text-ish SQL types.
|
||||
// This avoids converting custom modifiers like vector(1536) into Length.
|
||||
if pgsql.SupportsLength(rawBaseType) && !strings.Contains(parens, ",") {
|
||||
if _, err := fmt.Sscanf(parens, "%d", &length); err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
baseType = typeStr
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -71,8 +71,11 @@ func TestReader_ReadDatabase_Simple(t *testing.T) {
|
||||
if !emailCol.NotNull {
|
||||
t.Error("Column 'email' should be NOT NULL (explicit 'not null' tag)")
|
||||
}
|
||||
if emailCol.Type != "varchar" || emailCol.Length != 255 {
|
||||
t.Errorf("Expected email type 'varchar(255)', got '%s' with length %d", emailCol.Type, emailCol.Length)
|
||||
if emailCol.Type != "varchar" && emailCol.Type != "varchar(255)" {
|
||||
t.Errorf("Expected email type 'varchar' or 'varchar(255)', got '%s' with length %d", emailCol.Type, emailCol.Length)
|
||||
}
|
||||
if emailCol.Length != 255 {
|
||||
t.Errorf("Expected email length 255, got %d", emailCol.Length)
|
||||
}
|
||||
|
||||
// Verify name column - primitive string type should be NOT NULL by default
|
||||
@@ -363,6 +366,33 @@ func TestReader_ReadDatabase_Complex(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTypeWithLength_PreservesExplicitTypeModifiers(t *testing.T) {
|
||||
reader := &Reader{}
|
||||
|
||||
tests := []struct {
|
||||
input string
|
||||
wantType string
|
||||
wantLength int
|
||||
}{
|
||||
{"varchar(255)", "varchar(255)", 255},
|
||||
{"character varying(120)", "character varying(120)", 120},
|
||||
{"vector(1536)", "vector(1536)", 1536},
|
||||
{"numeric(10,2)", "numeric(10,2)", 0},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
gotType, gotLength := reader.parseTypeWithLength(tt.input)
|
||||
if gotType != tt.wantType {
|
||||
t.Fatalf("parseTypeWithLength(%q) type = %q, want %q", tt.input, gotType, tt.wantType)
|
||||
}
|
||||
if gotLength != tt.wantLength {
|
||||
t.Fatalf("parseTypeWithLength(%q) length = %d, want %d", tt.input, gotLength, tt.wantLength)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadSchema(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "gorm", "simple.go"),
|
||||
|
||||
Reference in New Issue
Block a user