Files
relspecgo/pkg/writers/dbml/writer_test.go
T
warkanum 161ac317f0
Release / test (push) Successful in 1m45s
Release / release (push) Successful in 12m24s
Release / pkg-rpm (push) Successful in 2m3s
Release / pkg-deb (push) Successful in 2m17s
Release / pkg-aur (push) Successful in 2m47s
feat(dbml): support multiline table notes in DBML
* Add parsing for triple-quoted table notes in DBML
* Update writer to format multiline notes correctly
* Enhance tests for multiline table notes handling
2026-09-09 21:38:11 +02:00

174 lines
5.5 KiB
Go

package dbml
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"git.warky.dev/wdevs/relspecgo/pkg/models"
"git.warky.dev/wdevs/relspecgo/pkg/writers"
)
func TestWriter_WriteTable(t *testing.T) {
table := models.InitTable("users", "public")
table.Description = "User accounts table"
idCol := models.InitColumn("id", "users", "public")
idCol.Type = "bigint"
idCol.IsPrimaryKey = true
idCol.AutoIncrement = true
idCol.NotNull = true
table.Columns["id"] = idCol
emailCol := models.InitColumn("email", "users", "public")
emailCol.Type = "varchar(255)"
emailCol.NotNull = true
table.Columns["email"] = emailCol
nameCol := models.InitColumn("name", "users", "public")
nameCol.Type = "varchar(100)"
nameCol.NotNull = false
table.Columns["name"] = nameCol
createdCol := models.InitColumn("created_at", "users", "public")
createdCol.Type = "timestamp"
createdCol.NotNull = true
createdCol.Default = "now()"
table.Columns["created_at"] = createdCol
tmpDir := t.TempDir()
outputPath := filepath.Join(tmpDir, "test.dbml")
opts := &writers.WriterOptions{
OutputPath: outputPath,
}
writer := NewWriter(opts)
err := writer.WriteTable(table)
assert.NoError(t, err)
content, err := os.ReadFile(outputPath)
assert.NoError(t, err)
output := string(content)
assert.Contains(t, output, "Table public.users {")
assert.Contains(t, output, "id bigint [pk, increment]")
assert.Contains(t, output, "email varchar(255) [not null]")
assert.Contains(t, output, "Note: 'User accounts table'")
}
func TestWriter_WriteTable_MultilineNote(t *testing.T) {
table := models.InitTable("cities", "info")
table.Description = "Cities and municipalities worldwide.\n\nSPATIAL:\nProximity queries use a GiST index."
outputPath := filepath.Join(t.TempDir(), "cities.dbml")
writer := NewWriter(&writers.WriterOptions{OutputPath: outputPath})
if err := writer.WriteTable(table); err != nil {
t.Fatalf("WriteTable() error = %v", err)
}
output, err := os.ReadFile(outputPath)
if err != nil {
t.Fatalf("failed to read generated DBML: %v", err)
}
assert.Contains(t, string(output), "Note: '''\nCities and municipalities worldwide.\n\nSPATIAL:\nProximity queries use a GiST index.\n '''")
}
func TestWriter_WriteDatabase_WithRelationships(t *testing.T) {
db := models.InitDatabase("test_db")
schema := models.InitSchema("public")
usersTable := models.InitTable("users", "public")
idCol := models.InitColumn("id", "users", "public")
idCol.Type = "bigint"
idCol.IsPrimaryKey = true
usersTable.Columns["id"] = idCol
emailIdx := models.InitIndex("idx_users_email", "users", "public")
emailIdx.Columns = []string{"email"}
emailIdx.Unique = true
usersTable.Indexes["idx_users_email"] = emailIdx
schema.Tables = append(schema.Tables, usersTable)
postsTable := models.InitTable("posts", "public")
postIdCol := models.InitColumn("id", "posts", "public")
postIdCol.Type = "bigint"
postsTable.Columns["id"] = postIdCol
userIdCol := models.InitColumn("user_id", "posts", "public")
userIdCol.Type = "bigint"
postsTable.Columns["user_id"] = userIdCol
fk := models.InitConstraint("fk_posts_user", models.ForeignKeyConstraint)
fk.Table = "posts"
fk.Schema = "public"
fk.Columns = []string{"user_id"}
fk.ReferencedTable = "users"
fk.ReferencedSchema = "public"
fk.ReferencedColumns = []string{"id"}
fk.OnDelete = "CASCADE"
postsTable.Constraints["fk_posts_user"] = fk
schema.Tables = append(schema.Tables, postsTable)
db.Schemas = append(db.Schemas, schema)
tmpDir := t.TempDir()
outputPath := filepath.Join(tmpDir, "test.dbml")
opts := &writers.WriterOptions{OutputPath: outputPath}
writer := NewWriter(opts)
err := writer.WriteDatabase(db)
assert.NoError(t, err)
content, err := os.ReadFile(outputPath)
assert.NoError(t, err)
output := string(content)
assert.Contains(t, output, "Table public.users {")
assert.Contains(t, output, "Table public.posts {")
assert.Contains(t, output, "Ref: public.posts.user_id > public.users.id [delete: CASCADE]")
assert.Contains(t, output, "(email) [unique, name: 'idx_users_email']")
}
func TestWriter_WriteDatabase_OneToOneRelationship(t *testing.T) {
db := models.InitDatabase("test_db")
schema := models.InitSchema("public")
usersTable := models.InitTable("users", "public")
idCol := models.InitColumn("id", "users", "public")
idCol.Type = "bigint"
idCol.IsPrimaryKey = true
usersTable.Columns["id"] = idCol
schema.Tables = append(schema.Tables, usersTable)
profilesTable := models.InitTable("profiles", "public")
profileIdCol := models.InitColumn("id", "profiles", "public")
profileIdCol.Type = "bigint"
profilesTable.Columns["id"] = profileIdCol
userIdCol := models.InitColumn("user_id", "profiles", "public")
userIdCol.Type = "bigint"
userIdCol.IsPrimaryKey = true // This makes it a one-to-one
profilesTable.Columns["user_id"] = userIdCol
fk := models.InitConstraint("fk_profiles_user", models.ForeignKeyConstraint)
fk.Table = "profiles"
fk.Schema = "public"
fk.Columns = []string{"user_id"}
fk.ReferencedTable = "users"
fk.ReferencedSchema = "public"
fk.ReferencedColumns = []string{"id"}
profilesTable.Constraints["fk_profiles_user"] = fk
schema.Tables = append(schema.Tables, profilesTable)
db.Schemas = append(db.Schemas, schema)
tmpDir := t.TempDir()
outputPath := filepath.Join(tmpDir, "test.dbml")
opts := &writers.WriterOptions{OutputPath: outputPath}
writer := NewWriter(opts)
err := writer.WriteDatabase(db)
assert.NoError(t, err)
content, err := os.ReadFile(outputPath)
assert.NoError(t, err)
output := string(content)
assert.Contains(t, output, "Ref: public.profiles.user_id - public.users.id")
}