package dbml import ( "os" "path/filepath" "testing" dbmlreader "git.warky.dev/wdevs/relspecgo/pkg/readers/dbml" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "git.warky.dev/wdevs/relspecgo/pkg/models" "git.warky.dev/wdevs/relspecgo/pkg/readers" "git.warky.dev/wdevs/relspecgo/pkg/writers" ) const directiveSrc = `@postgres: search_path myapp Table myapp.events { id bigint [pk] created_at timestamp [not null] @postgres(id): identity always @postgres: partition by RANGE (created_at) @postgres: tablespace fast_data @sqlite: without rowid indexes { (created_at) [name: 'idx_events_created'] @postgres: with (fillfactor=90) } } ` func writeDBML(t *testing.T, db *models.Database) string { t.Helper() out := filepath.Join(t.TempDir(), "out.dbml") require.NoError(t, NewWriter(&writers.WriterOptions{OutputPath: out}).WriteDatabase(db)) b, err := os.ReadFile(out) require.NoError(t, err) return string(b) } func readDBML(t *testing.T, src string) *models.Database { t.Helper() f := filepath.Join(t.TempDir(), "in.dbml") require.NoError(t, os.WriteFile(f, []byte(src), 0o644)) db, err := dbmlreader.NewReader(&readers.ReaderOptions{FilePath: f}).ReadDatabase() require.NoError(t, err) return db } func collectDirectives(db *models.Database) map[string][]string { got := map[string][]string{} add := func(loc string, meta map[string]any) { for _, d := range models.GetDirectives(meta) { got[loc] = append(got[loc], models.FormatDirectiveLine(d, "")) } } add("database", db.Metadata) for _, s := range db.Schemas { for _, tbl := range s.Tables { add("table:"+tbl.Name, tbl.Metadata) for _, c := range tbl.Columns { add("column:"+c.Name, c.Metadata) } for _, i := range tbl.Indexes { add("index:"+i.Name, i.Metadata) } } } return got } func TestDirectives_RoundTrip(t *testing.T) { db1 := readDBML(t, directiveSrc) out1 := writeDBML(t, db1) db2 := readDBML(t, out1) out2 := writeDBML(t, db2) assert.Equal(t, out1, out2, "DBML directive output should be idempotent") assert.Equal(t, collectDirectives(db1), collectDirectives(db2), "directives preserved through round-trip") // Spot-check each location survived. d := collectDirectives(db2) assert.Contains(t, d["database"], "@postgres: search_path myapp") assert.Contains(t, d["table:events"], "@postgres: partition by RANGE (created_at)") assert.Contains(t, d["table:events"], "@sqlite: without rowid") assert.Contains(t, d["column:id"], "@postgres: identity always") assert.Contains(t, d["index:idx_events_created"], "@postgres: with (fillfactor=90)") } func TestDirectives_WriterEmitsColumnTarget(t *testing.T) { db := readDBML(t, directiveSrc) out := writeDBML(t, db) assert.Contains(t, out, "@postgres(id): identity always") }