fix(bun): support extra generated model fields
This commit is contained in:
@@ -855,6 +855,166 @@ func TestTypeMapper_BuildBunTag_StdlibArrayHasArrayTag(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtraFields_LoadFromMetadata(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
metadata map[string]interface{}
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
name: "nil metadata",
|
||||
metadata: nil,
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "no extra_fields key",
|
||||
metadata: map[string]interface{}{
|
||||
"generate_table_name": true,
|
||||
},
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "empty array",
|
||||
metadata: map[string]interface{}{
|
||||
"extra_fields": []interface{}{},
|
||||
},
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
name: "JSON string format",
|
||||
metadata: map[string]interface{}{
|
||||
"extra_fields": `[{"name":"ThoughtCount","type":"int64","bun_tag":"thought_count,scanonly","json_tag":"thought_count"}]`,
|
||||
},
|
||||
expected: 1,
|
||||
},
|
||||
{
|
||||
name: "structured format",
|
||||
metadata: map[string]interface{}{
|
||||
"extra_fields": []interface{}{
|
||||
map[string]interface{}{
|
||||
"name": "ThoughtCount",
|
||||
"type": "int64",
|
||||
"bun_tag": "thought_count,scanonly",
|
||||
"json_tag": "thought_count",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
fields := LoadExtraFieldsFromMetadata(tt.metadata)
|
||||
if len(fields) != tt.expected {
|
||||
t.Errorf("expected %d fields, got %d", tt.expected, len(fields))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtraFields_InSingleFile(t *testing.T) {
|
||||
table := models.InitTable("projects", "public")
|
||||
table.Columns["id"] = &models.Column{
|
||||
Name: "id",
|
||||
Type: "bigint",
|
||||
NotNull: true,
|
||||
IsPrimaryKey: true,
|
||||
}
|
||||
table.Columns["name"] = &models.Column{
|
||||
Name: "name",
|
||||
Type: "varchar",
|
||||
Length: 255,
|
||||
Sequence: 1,
|
||||
}
|
||||
|
||||
opts := &writers.WriterOptions{
|
||||
PackageName: "models",
|
||||
OutputPath: t.TempDir() + "/test.go",
|
||||
Metadata: map[string]interface{}{
|
||||
"extra_fields": `[{"name":"ThoughtCount","type":"int64","bun_tag":"thought_count,scanonly","json_tag":"thought_count"}]`,
|
||||
},
|
||||
}
|
||||
|
||||
writer := NewWriter(opts)
|
||||
err := writer.WriteTable(table)
|
||||
if err != nil {
|
||||
t.Fatalf("WriteTable failed: %v", err)
|
||||
}
|
||||
|
||||
content, _ := os.ReadFile(opts.OutputPath)
|
||||
generated := string(content)
|
||||
|
||||
// Verify extra field is present with separator comment
|
||||
expectations := []string{
|
||||
"// --- Custom fields (managed by relspecgo generator config, issue #4) ---",
|
||||
"ThoughtCount int64 `bun:\"thought_count,scanonly\" json:\"thought_count\"`",
|
||||
}
|
||||
|
||||
for _, expected := range expectations {
|
||||
if !strings.Contains(generated, expected) {
|
||||
t.Errorf("Generated code missing: %q\nGenerated:\n%s", expected, generated)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtraFields_InMultiFile(t *testing.T) {
|
||||
db := models.InitDatabase("testdb")
|
||||
schema := models.InitSchema("public")
|
||||
|
||||
users := models.InitTable("users", "public")
|
||||
users.Columns["id"] = &models.Column{
|
||||
Name: "id",
|
||||
Type: "bigint",
|
||||
NotNull: true,
|
||||
IsPrimaryKey: true,
|
||||
}
|
||||
schema.Tables = append(schema.Tables, users)
|
||||
|
||||
posts := models.InitTable("posts", "public")
|
||||
posts.Columns["id"] = &models.Column{
|
||||
Name: "id",
|
||||
Type: "bigint",
|
||||
NotNull: true,
|
||||
IsPrimaryKey: true,
|
||||
}
|
||||
schema.Tables = append(schema.Tables, posts)
|
||||
|
||||
db.Schemas = append(db.Schemas, schema)
|
||||
|
||||
tmpDir := t.TempDir()
|
||||
opts := &writers.WriterOptions{
|
||||
PackageName: "models",
|
||||
OutputPath: tmpDir,
|
||||
Metadata: map[string]interface{}{
|
||||
"multi_file": true,
|
||||
"extra_fields": `[{"target_table":"users","name":"PostCount","type":"int64","bun_tag":"post_count,scanonly","json_tag":"post_count"}]`,
|
||||
},
|
||||
}
|
||||
|
||||
writer := NewWriter(opts)
|
||||
err := writer.WriteDatabase(db)
|
||||
if err != nil {
|
||||
t.Fatalf("WriteDatabase failed: %v", err)
|
||||
}
|
||||
|
||||
// Check users file has the extra field (matched by table name "users")
|
||||
usersContent, _ := os.ReadFile(tmpDir + "/sql_public_users.go")
|
||||
usersStr := string(usersContent)
|
||||
|
||||
if !strings.Contains(usersStr, "PostCount int64 `bun:\"post_count,scanonly\"") {
|
||||
t.Errorf("Extra field not found in users file:\n%s", usersStr)
|
||||
}
|
||||
|
||||
// Posts file should NOT have the extra field (name mismatch)
|
||||
postsContent, _ := os.ReadFile(tmpDir + "/sql_public_posts.go")
|
||||
postsStr := string(postsContent)
|
||||
|
||||
if strings.Contains(postsStr, "PostCount") {
|
||||
t.Errorf("Extra field should not be in posts file:\n%s", postsStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypeMapper_BuildBunTag_PreservesExplicitTypeModifiers(t *testing.T) {
|
||||
mapper := NewTypeMapper("")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user