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:
714
pkg/commontypes/commontypes_test.go
Normal file
714
pkg/commontypes/commontypes_test.go
Normal file
@@ -0,0 +1,714 @@
|
||||
package commontypes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestExtractBaseType(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
want string
|
||||
}{
|
||||
{"varchar with length", "varchar(100)", "varchar"},
|
||||
{"VARCHAR uppercase with length", "VARCHAR(255)", "varchar"},
|
||||
{"numeric with precision", "numeric(10,2)", "numeric"},
|
||||
{"NUMERIC uppercase", "NUMERIC(18,4)", "numeric"},
|
||||
{"decimal with precision", "decimal(15,3)", "decimal"},
|
||||
{"char with length", "char(50)", "char"},
|
||||
{"simple integer", "integer", "integer"},
|
||||
{"simple text", "text", "text"},
|
||||
{"bigint", "bigint", "bigint"},
|
||||
{"With spaces", " varchar(100) ", "varchar"},
|
||||
{"No parentheses", "boolean", "boolean"},
|
||||
{"Empty string", "", ""},
|
||||
{"Mixed case", "VarChar(100)", "varchar"},
|
||||
{"timestamp with time zone", "timestamp(6) with time zone", "timestamp"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := ExtractBaseType(tt.sqlType)
|
||||
if got != tt.want {
|
||||
t.Errorf("ExtractBaseType(%q) = %q, want %q", tt.sqlType, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeType(t *testing.T) {
|
||||
// NormalizeType is an alias for ExtractBaseType, test that they behave the same
|
||||
testCases := []string{
|
||||
"varchar(100)",
|
||||
"numeric(10,2)",
|
||||
"integer",
|
||||
"text",
|
||||
" VARCHAR(255) ",
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc, func(t *testing.T) {
|
||||
extracted := ExtractBaseType(tc)
|
||||
normalized := NormalizeType(tc)
|
||||
if extracted != normalized {
|
||||
t.Errorf("ExtractBaseType(%q) = %q, but NormalizeType(%q) = %q",
|
||||
tc, extracted, tc, normalized)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLToGo(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
nullable bool
|
||||
want string
|
||||
}{
|
||||
// Integer types (nullable)
|
||||
{"integer nullable", "integer", true, "int32"},
|
||||
{"bigint nullable", "bigint", true, "int64"},
|
||||
{"smallint nullable", "smallint", true, "int16"},
|
||||
{"serial nullable", "serial", true, "int32"},
|
||||
|
||||
// Integer types (not nullable)
|
||||
{"integer not nullable", "integer", false, "*int32"},
|
||||
{"bigint not nullable", "bigint", false, "*int64"},
|
||||
{"smallint not nullable", "smallint", false, "*int16"},
|
||||
|
||||
// String types (nullable)
|
||||
{"text nullable", "text", true, "string"},
|
||||
{"varchar nullable", "varchar", true, "string"},
|
||||
{"varchar with length nullable", "varchar(100)", true, "string"},
|
||||
|
||||
// String types (not nullable)
|
||||
{"text not nullable", "text", false, "*string"},
|
||||
{"varchar not nullable", "varchar", false, "*string"},
|
||||
|
||||
// Boolean
|
||||
{"boolean nullable", "boolean", true, "bool"},
|
||||
{"boolean not nullable", "boolean", false, "*bool"},
|
||||
|
||||
// Float types
|
||||
{"real nullable", "real", true, "float32"},
|
||||
{"double precision nullable", "double precision", true, "float64"},
|
||||
{"real not nullable", "real", false, "*float32"},
|
||||
{"double precision not nullable", "double precision", false, "*float64"},
|
||||
|
||||
// Date/Time types
|
||||
{"timestamp nullable", "timestamp", true, "time.Time"},
|
||||
{"date nullable", "date", true, "time.Time"},
|
||||
{"timestamp not nullable", "timestamp", false, "*time.Time"},
|
||||
|
||||
// Binary
|
||||
{"bytea nullable", "bytea", true, "[]byte"},
|
||||
{"bytea not nullable", "bytea", false, "[]byte"}, // Slices don't get pointer
|
||||
|
||||
// UUID
|
||||
{"uuid nullable", "uuid", true, "string"},
|
||||
{"uuid not nullable", "uuid", false, "*string"},
|
||||
|
||||
// JSON
|
||||
{"json nullable", "json", true, "string"},
|
||||
{"jsonb nullable", "jsonb", true, "string"},
|
||||
|
||||
// Array
|
||||
{"array nullable", "array", true, "[]string"},
|
||||
{"array not nullable", "array", false, "[]string"}, // Slices don't get pointer
|
||||
|
||||
// Unknown types
|
||||
{"unknown type nullable", "unknowntype", true, "interface{}"},
|
||||
{"unknown type not nullable", "unknowntype", false, "interface{}"}, // Interface doesn't get pointer
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SQLToGo(tt.sqlType, tt.nullable)
|
||||
if got != tt.want {
|
||||
t.Errorf("SQLToGo(%q, %v) = %q, want %q", tt.sqlType, tt.nullable, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLToTypeScript(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
nullable bool
|
||||
want string
|
||||
}{
|
||||
// Integer types
|
||||
{"integer nullable", "integer", true, "number"},
|
||||
{"integer not nullable", "integer", false, "number | null"},
|
||||
{"bigint nullable", "bigint", true, "number"},
|
||||
{"bigint not nullable", "bigint", false, "number | null"},
|
||||
|
||||
// String types
|
||||
{"text nullable", "text", true, "string"},
|
||||
{"text not nullable", "text", false, "string | null"},
|
||||
{"varchar nullable", "varchar", true, "string"},
|
||||
{"varchar(100) nullable", "varchar(100)", true, "string"},
|
||||
|
||||
// Boolean
|
||||
{"boolean nullable", "boolean", true, "boolean"},
|
||||
{"boolean not nullable", "boolean", false, "boolean | null"},
|
||||
|
||||
// Float types
|
||||
{"real nullable", "real", true, "number"},
|
||||
{"double precision nullable", "double precision", true, "number"},
|
||||
|
||||
// Date/Time types
|
||||
{"timestamp nullable", "timestamp", true, "Date"},
|
||||
{"date nullable", "date", true, "Date"},
|
||||
{"timestamp not nullable", "timestamp", false, "Date | null"},
|
||||
|
||||
// Binary
|
||||
{"bytea nullable", "bytea", true, "Buffer"},
|
||||
{"bytea not nullable", "bytea", false, "Buffer | null"},
|
||||
|
||||
// JSON
|
||||
{"json nullable", "json", true, "any"},
|
||||
{"jsonb nullable", "jsonb", true, "any"},
|
||||
|
||||
// UUID
|
||||
{"uuid nullable", "uuid", true, "string"},
|
||||
|
||||
// Unknown types
|
||||
{"unknown type nullable", "unknowntype", true, "any"},
|
||||
{"unknown type not nullable", "unknowntype", false, "any | null"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SQLToTypeScript(tt.sqlType, tt.nullable)
|
||||
if got != tt.want {
|
||||
t.Errorf("SQLToTypeScript(%q, %v) = %q, want %q", tt.sqlType, tt.nullable, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLToPython(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
want string
|
||||
}{
|
||||
// Integer types
|
||||
{"integer", "integer", "int"},
|
||||
{"bigint", "bigint", "int"},
|
||||
{"smallint", "smallint", "int"},
|
||||
|
||||
// String types
|
||||
{"text", "text", "str"},
|
||||
{"varchar", "varchar", "str"},
|
||||
{"varchar(100)", "varchar(100)", "str"},
|
||||
|
||||
// Boolean
|
||||
{"boolean", "boolean", "bool"},
|
||||
|
||||
// Float types
|
||||
{"real", "real", "float"},
|
||||
{"double precision", "double precision", "float"},
|
||||
{"numeric", "numeric", "Decimal"},
|
||||
{"decimal", "decimal", "Decimal"},
|
||||
|
||||
// Date/Time types
|
||||
{"timestamp", "timestamp", "datetime"},
|
||||
{"date", "date", "date"},
|
||||
{"time", "time", "time"},
|
||||
|
||||
// Binary
|
||||
{"bytea", "bytea", "bytes"},
|
||||
|
||||
// JSON
|
||||
{"json", "json", "dict"},
|
||||
{"jsonb", "jsonb", "dict"},
|
||||
|
||||
// UUID
|
||||
{"uuid", "uuid", "UUID"},
|
||||
|
||||
// Array
|
||||
{"array", "array", "list"},
|
||||
|
||||
// Unknown types
|
||||
{"unknown type", "unknowntype", "Any"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SQLToPython(tt.sqlType)
|
||||
if got != tt.want {
|
||||
t.Errorf("SQLToPython(%q) = %q, want %q", tt.sqlType, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLToCSharp(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
nullable bool
|
||||
want string
|
||||
}{
|
||||
// Integer types (nullable)
|
||||
{"integer nullable", "integer", true, "int"},
|
||||
{"bigint nullable", "bigint", true, "long"},
|
||||
{"smallint nullable", "smallint", true, "short"},
|
||||
|
||||
// Integer types (not nullable - value types get ?)
|
||||
{"integer not nullable", "integer", false, "int?"},
|
||||
{"bigint not nullable", "bigint", false, "long?"},
|
||||
{"smallint not nullable", "smallint", false, "short?"},
|
||||
|
||||
// String types (reference types, no ? needed)
|
||||
{"text nullable", "text", true, "string"},
|
||||
{"text not nullable", "text", false, "string"},
|
||||
{"varchar nullable", "varchar", true, "string"},
|
||||
{"varchar(100) nullable", "varchar(100)", true, "string"},
|
||||
|
||||
// Boolean
|
||||
{"boolean nullable", "boolean", true, "bool"},
|
||||
{"boolean not nullable", "boolean", false, "bool?"},
|
||||
|
||||
// Float types
|
||||
{"real nullable", "real", true, "float"},
|
||||
{"double precision nullable", "double precision", true, "double"},
|
||||
{"decimal nullable", "decimal", true, "decimal"},
|
||||
{"real not nullable", "real", false, "float?"},
|
||||
{"double precision not nullable", "double precision", false, "double?"},
|
||||
{"decimal not nullable", "decimal", false, "decimal?"},
|
||||
|
||||
// Date/Time types
|
||||
{"timestamp nullable", "timestamp", true, "DateTime"},
|
||||
{"date nullable", "date", true, "DateTime"},
|
||||
{"timestamptz nullable", "timestamptz", true, "DateTimeOffset"},
|
||||
{"timestamp not nullable", "timestamp", false, "DateTime?"},
|
||||
{"timestamptz not nullable", "timestamptz", false, "DateTimeOffset?"},
|
||||
|
||||
// Binary (array type, no ?)
|
||||
{"bytea nullable", "bytea", true, "byte[]"},
|
||||
{"bytea not nullable", "bytea", false, "byte[]"},
|
||||
|
||||
// UUID
|
||||
{"uuid nullable", "uuid", true, "Guid"},
|
||||
{"uuid not nullable", "uuid", false, "Guid?"},
|
||||
|
||||
// JSON
|
||||
{"json nullable", "json", true, "string"},
|
||||
|
||||
// Unknown types (object is reference type)
|
||||
{"unknown type nullable", "unknowntype", true, "object"},
|
||||
{"unknown type not nullable", "unknowntype", false, "object"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SQLToCSharp(tt.sqlType, tt.nullable)
|
||||
if got != tt.want {
|
||||
t.Errorf("SQLToCSharp(%q, %v) = %q, want %q", tt.sqlType, tt.nullable, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNeedsTimeImport(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
goType string
|
||||
want bool
|
||||
}{
|
||||
{"time.Time type", "time.Time", true},
|
||||
{"pointer to time.Time", "*time.Time", true},
|
||||
{"int32 type", "int32", false},
|
||||
{"string type", "string", false},
|
||||
{"bool type", "bool", false},
|
||||
{"[]byte type", "[]byte", false},
|
||||
{"interface{}", "interface{}", false},
|
||||
{"empty string", "", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := NeedsTimeImport(tt.goType)
|
||||
if got != tt.want {
|
||||
t.Errorf("NeedsTimeImport(%q) = %v, want %v", tt.goType, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoTypeMap(t *testing.T) {
|
||||
// Test that the map contains expected entries
|
||||
expectedMappings := map[string]string{
|
||||
"integer": "int32",
|
||||
"bigint": "int64",
|
||||
"text": "string",
|
||||
"boolean": "bool",
|
||||
"double precision": "float64",
|
||||
"bytea": "[]byte",
|
||||
"timestamp": "time.Time",
|
||||
"uuid": "string",
|
||||
"json": "string",
|
||||
}
|
||||
|
||||
for sqlType, expectedGoType := range expectedMappings {
|
||||
if goType, ok := GoTypeMap[sqlType]; !ok {
|
||||
t.Errorf("GoTypeMap missing entry for %q", sqlType)
|
||||
} else if goType != expectedGoType {
|
||||
t.Errorf("GoTypeMap[%q] = %q, want %q", sqlType, goType, expectedGoType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(GoTypeMap) == 0 {
|
||||
t.Error("GoTypeMap is empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeScriptTypeMap(t *testing.T) {
|
||||
expectedMappings := map[string]string{
|
||||
"integer": "number",
|
||||
"bigint": "number",
|
||||
"text": "string",
|
||||
"boolean": "boolean",
|
||||
"double precision": "number",
|
||||
"bytea": "Buffer",
|
||||
"timestamp": "Date",
|
||||
"uuid": "string",
|
||||
"json": "any",
|
||||
}
|
||||
|
||||
for sqlType, expectedTSType := range expectedMappings {
|
||||
if tsType, ok := TypeScriptTypeMap[sqlType]; !ok {
|
||||
t.Errorf("TypeScriptTypeMap missing entry for %q", sqlType)
|
||||
} else if tsType != expectedTSType {
|
||||
t.Errorf("TypeScriptTypeMap[%q] = %q, want %q", sqlType, tsType, expectedTSType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(TypeScriptTypeMap) == 0 {
|
||||
t.Error("TypeScriptTypeMap is empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPythonTypeMap(t *testing.T) {
|
||||
expectedMappings := map[string]string{
|
||||
"integer": "int",
|
||||
"bigint": "int",
|
||||
"text": "str",
|
||||
"boolean": "bool",
|
||||
"real": "float",
|
||||
"numeric": "Decimal",
|
||||
"bytea": "bytes",
|
||||
"date": "date",
|
||||
"uuid": "UUID",
|
||||
"json": "dict",
|
||||
}
|
||||
|
||||
for sqlType, expectedPyType := range expectedMappings {
|
||||
if pyType, ok := PythonTypeMap[sqlType]; !ok {
|
||||
t.Errorf("PythonTypeMap missing entry for %q", sqlType)
|
||||
} else if pyType != expectedPyType {
|
||||
t.Errorf("PythonTypeMap[%q] = %q, want %q", sqlType, pyType, expectedPyType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(PythonTypeMap) == 0 {
|
||||
t.Error("PythonTypeMap is empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCSharpTypeMap(t *testing.T) {
|
||||
expectedMappings := map[string]string{
|
||||
"integer": "int",
|
||||
"bigint": "long",
|
||||
"smallint": "short",
|
||||
"text": "string",
|
||||
"boolean": "bool",
|
||||
"double precision": "double",
|
||||
"decimal": "decimal",
|
||||
"bytea": "byte[]",
|
||||
"timestamp": "DateTime",
|
||||
"uuid": "Guid",
|
||||
"json": "string",
|
||||
}
|
||||
|
||||
for sqlType, expectedCSType := range expectedMappings {
|
||||
if csType, ok := CSharpTypeMap[sqlType]; !ok {
|
||||
t.Errorf("CSharpTypeMap missing entry for %q", sqlType)
|
||||
} else if csType != expectedCSType {
|
||||
t.Errorf("CSharpTypeMap[%q] = %q, want %q", sqlType, csType, expectedCSType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(CSharpTypeMap) == 0 {
|
||||
t.Error("CSharpTypeMap is empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLToJava(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
nullable bool
|
||||
want string
|
||||
}{
|
||||
// Integer types
|
||||
{"integer nullable", "integer", true, "Integer"},
|
||||
{"integer not nullable", "integer", false, "Integer"},
|
||||
{"bigint nullable", "bigint", true, "Long"},
|
||||
{"smallint nullable", "smallint", true, "Short"},
|
||||
|
||||
// String types
|
||||
{"text nullable", "text", true, "String"},
|
||||
{"varchar nullable", "varchar", true, "String"},
|
||||
{"varchar(100) nullable", "varchar(100)", true, "String"},
|
||||
|
||||
// Boolean
|
||||
{"boolean nullable", "boolean", true, "Boolean"},
|
||||
|
||||
// Float types
|
||||
{"real nullable", "real", true, "Float"},
|
||||
{"double precision nullable", "double precision", true, "Double"},
|
||||
{"numeric nullable", "numeric", true, "BigDecimal"},
|
||||
|
||||
// Date/Time types
|
||||
{"timestamp nullable", "timestamp", true, "Timestamp"},
|
||||
{"date nullable", "date", true, "Date"},
|
||||
{"time nullable", "time", true, "Time"},
|
||||
|
||||
// Binary
|
||||
{"bytea nullable", "bytea", true, "byte[]"},
|
||||
|
||||
// UUID
|
||||
{"uuid nullable", "uuid", true, "UUID"},
|
||||
|
||||
// JSON
|
||||
{"json nullable", "json", true, "String"},
|
||||
|
||||
// Unknown types
|
||||
{"unknown type nullable", "unknowntype", true, "Object"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SQLToJava(tt.sqlType, tt.nullable)
|
||||
if got != tt.want {
|
||||
t.Errorf("SQLToJava(%q, %v) = %q, want %q", tt.sqlType, tt.nullable, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLToPhp(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
nullable bool
|
||||
want string
|
||||
}{
|
||||
// Integer types (nullable)
|
||||
{"integer nullable", "integer", true, "int"},
|
||||
{"bigint nullable", "bigint", true, "int"},
|
||||
{"smallint nullable", "smallint", true, "int"},
|
||||
|
||||
// Integer types (not nullable)
|
||||
{"integer not nullable", "integer", false, "?int"},
|
||||
{"bigint not nullable", "bigint", false, "?int"},
|
||||
|
||||
// String types
|
||||
{"text nullable", "text", true, "string"},
|
||||
{"text not nullable", "text", false, "?string"},
|
||||
{"varchar nullable", "varchar", true, "string"},
|
||||
{"varchar(100) nullable", "varchar(100)", true, "string"},
|
||||
|
||||
// Boolean
|
||||
{"boolean nullable", "boolean", true, "bool"},
|
||||
{"boolean not nullable", "boolean", false, "?bool"},
|
||||
|
||||
// Float types
|
||||
{"real nullable", "real", true, "float"},
|
||||
{"double precision nullable", "double precision", true, "float"},
|
||||
{"real not nullable", "real", false, "?float"},
|
||||
|
||||
// Date/Time types
|
||||
{"timestamp nullable", "timestamp", true, "\\DateTime"},
|
||||
{"date nullable", "date", true, "\\DateTime"},
|
||||
{"timestamp not nullable", "timestamp", false, "?\\DateTime"},
|
||||
|
||||
// Binary
|
||||
{"bytea nullable", "bytea", true, "string"},
|
||||
{"bytea not nullable", "bytea", false, "?string"},
|
||||
|
||||
// JSON
|
||||
{"json nullable", "json", true, "array"},
|
||||
{"json not nullable", "json", false, "?array"},
|
||||
|
||||
// UUID
|
||||
{"uuid nullable", "uuid", true, "string"},
|
||||
|
||||
// Unknown types
|
||||
{"unknown type nullable", "unknowntype", true, "mixed"},
|
||||
{"unknown type not nullable", "unknowntype", false, "mixed"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SQLToPhp(tt.sqlType, tt.nullable)
|
||||
if got != tt.want {
|
||||
t.Errorf("SQLToPhp(%q, %v) = %q, want %q", tt.sqlType, tt.nullable, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSQLToRust(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sqlType string
|
||||
nullable bool
|
||||
want string
|
||||
}{
|
||||
// Integer types (nullable)
|
||||
{"integer nullable", "integer", true, "i32"},
|
||||
{"bigint nullable", "bigint", true, "i64"},
|
||||
{"smallint nullable", "smallint", true, "i16"},
|
||||
|
||||
// Integer types (not nullable)
|
||||
{"integer not nullable", "integer", false, "Option<i32>"},
|
||||
{"bigint not nullable", "bigint", false, "Option<i64>"},
|
||||
{"smallint not nullable", "smallint", false, "Option<i16>"},
|
||||
|
||||
// String types
|
||||
{"text nullable", "text", true, "String"},
|
||||
{"text not nullable", "text", false, "Option<String>"},
|
||||
{"varchar nullable", "varchar", true, "String"},
|
||||
{"varchar(100) nullable", "varchar(100)", true, "String"},
|
||||
|
||||
// Boolean
|
||||
{"boolean nullable", "boolean", true, "bool"},
|
||||
{"boolean not nullable", "boolean", false, "Option<bool>"},
|
||||
|
||||
// Float types
|
||||
{"real nullable", "real", true, "f32"},
|
||||
{"double precision nullable", "double precision", true, "f64"},
|
||||
{"real not nullable", "real", false, "Option<f32>"},
|
||||
{"double precision not nullable", "double precision", false, "Option<f64>"},
|
||||
|
||||
// Date/Time types
|
||||
{"timestamp nullable", "timestamp", true, "NaiveDateTime"},
|
||||
{"timestamptz nullable", "timestamptz", true, "DateTime<Utc>"},
|
||||
{"date nullable", "date", true, "NaiveDate"},
|
||||
{"time nullable", "time", true, "NaiveTime"},
|
||||
{"timestamp not nullable", "timestamp", false, "Option<NaiveDateTime>"},
|
||||
|
||||
// Binary
|
||||
{"bytea nullable", "bytea", true, "Vec<u8>"},
|
||||
{"bytea not nullable", "bytea", false, "Option<Vec<u8>>"},
|
||||
|
||||
// JSON
|
||||
{"json nullable", "json", true, "serde_json::Value"},
|
||||
{"json not nullable", "json", false, "Option<serde_json::Value>"},
|
||||
|
||||
// UUID
|
||||
{"uuid nullable", "uuid", true, "String"},
|
||||
|
||||
// Unknown types
|
||||
{"unknown type nullable", "unknowntype", true, "String"},
|
||||
{"unknown type not nullable", "unknowntype", false, "Option<String>"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := SQLToRust(tt.sqlType, tt.nullable)
|
||||
if got != tt.want {
|
||||
t.Errorf("SQLToRust(%q, %v) = %q, want %q", tt.sqlType, tt.nullable, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestJavaTypeMap(t *testing.T) {
|
||||
expectedMappings := map[string]string{
|
||||
"integer": "Integer",
|
||||
"bigint": "Long",
|
||||
"smallint": "Short",
|
||||
"text": "String",
|
||||
"boolean": "Boolean",
|
||||
"double precision": "Double",
|
||||
"numeric": "BigDecimal",
|
||||
"bytea": "byte[]",
|
||||
"timestamp": "Timestamp",
|
||||
"uuid": "UUID",
|
||||
"date": "Date",
|
||||
}
|
||||
|
||||
for sqlType, expectedJavaType := range expectedMappings {
|
||||
if javaType, ok := JavaTypeMap[sqlType]; !ok {
|
||||
t.Errorf("JavaTypeMap missing entry for %q", sqlType)
|
||||
} else if javaType != expectedJavaType {
|
||||
t.Errorf("JavaTypeMap[%q] = %q, want %q", sqlType, javaType, expectedJavaType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(JavaTypeMap) == 0 {
|
||||
t.Error("JavaTypeMap is empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPHPTypeMap(t *testing.T) {
|
||||
expectedMappings := map[string]string{
|
||||
"integer": "int",
|
||||
"bigint": "int",
|
||||
"text": "string",
|
||||
"boolean": "bool",
|
||||
"double precision": "float",
|
||||
"bytea": "string",
|
||||
"timestamp": "\\DateTime",
|
||||
"uuid": "string",
|
||||
"json": "array",
|
||||
}
|
||||
|
||||
for sqlType, expectedPHPType := range expectedMappings {
|
||||
if phpType, ok := PHPTypeMap[sqlType]; !ok {
|
||||
t.Errorf("PHPTypeMap missing entry for %q", sqlType)
|
||||
} else if phpType != expectedPHPType {
|
||||
t.Errorf("PHPTypeMap[%q] = %q, want %q", sqlType, phpType, expectedPHPType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(PHPTypeMap) == 0 {
|
||||
t.Error("PHPTypeMap is empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRustTypeMap(t *testing.T) {
|
||||
expectedMappings := map[string]string{
|
||||
"integer": "i32",
|
||||
"bigint": "i64",
|
||||
"smallint": "i16",
|
||||
"text": "String",
|
||||
"boolean": "bool",
|
||||
"double precision": "f64",
|
||||
"real": "f32",
|
||||
"bytea": "Vec<u8>",
|
||||
"timestamp": "NaiveDateTime",
|
||||
"timestamptz": "DateTime<Utc>",
|
||||
"date": "NaiveDate",
|
||||
"json": "serde_json::Value",
|
||||
}
|
||||
|
||||
for sqlType, expectedRustType := range expectedMappings {
|
||||
if rustType, ok := RustTypeMap[sqlType]; !ok {
|
||||
t.Errorf("RustTypeMap missing entry for %q", sqlType)
|
||||
} else if rustType != expectedRustType {
|
||||
t.Errorf("RustTypeMap[%q] = %q, want %q", sqlType, rustType, expectedRustType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(RustTypeMap) == 0 {
|
||||
t.Error("RustTypeMap is empty")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user