Files
relspecgo/tests/integration/orm_roundtrip_test.go
Hein bed4f5d3bd
Some checks are pending
CI / Test (1.23) (push) Waiting to run
CI / Test (1.24) (push) Waiting to run
CI / Test (1.25) (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Build (push) Waiting to run
better tests
2025-12-17 23:05:36 +02:00

315 lines
10 KiB
Go

package integration
import (
"os"
"path/filepath"
"testing"
"git.warky.dev/wdevs/relspecgo/pkg/models"
"git.warky.dev/wdevs/relspecgo/pkg/readers"
bunreader "git.warky.dev/wdevs/relspecgo/pkg/readers/bun"
gormreader "git.warky.dev/wdevs/relspecgo/pkg/readers/gorm"
yamlreader "git.warky.dev/wdevs/relspecgo/pkg/readers/yaml"
"git.warky.dev/wdevs/relspecgo/pkg/writers"
bunwriter "git.warky.dev/wdevs/relspecgo/pkg/writers/bun"
gormwriter "git.warky.dev/wdevs/relspecgo/pkg/writers/gorm"
yamlwriter "git.warky.dev/wdevs/relspecgo/pkg/writers/yaml"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"
)
// TestYAMLToBunRoundTrip tests YAML → Bun Go → YAML roundtrip
func TestYAMLToBunRoundTrip(t *testing.T) {
testDir := t.TempDir()
// Step 1: Read YAML file
t.Log("Step 1: Reading YAML file...")
yamlPath := filepath.Join("..", "assets", "yaml", "database.yaml")
yamlReaderOpts := &readers.ReaderOptions{
FilePath: yamlPath,
}
yamlReader := yamlreader.NewReader(yamlReaderOpts)
dbFromYAML, err := yamlReader.ReadDatabase()
require.NoError(t, err, "Failed to read YAML file")
require.NotNil(t, dbFromYAML, "Database from YAML should not be nil")
t.Logf(" ✓ Read database '%s' with %d schemas", dbFromYAML.Name, len(dbFromYAML.Schemas))
// Step 2: Write to Bun Go code
t.Log("Step 2: Writing to Bun Go code...")
bunGoPath := filepath.Join(testDir, "models_bun.go")
bunWriterOpts := &writers.WriterOptions{
OutputPath: bunGoPath,
PackageName: "models",
Metadata: map[string]interface{}{
"generate_table_name": true,
"generate_get_id": false,
},
}
bunWriter := bunwriter.NewWriter(bunWriterOpts)
err = bunWriter.WriteDatabase(dbFromYAML)
require.NoError(t, err, "Failed to write Bun Go code")
bunStat, err := os.Stat(bunGoPath)
require.NoError(t, err, "Bun Go file should exist")
require.Greater(t, bunStat.Size(), int64(0), "Bun Go file should not be empty")
t.Logf(" ✓ Wrote Bun Go file (%d bytes)", bunStat.Size())
// Step 3: Read Bun Go code back
t.Log("Step 3: Reading Bun Go code back...")
bunReaderOpts := &readers.ReaderOptions{
FilePath: bunGoPath,
}
bunReader := bunreader.NewReader(bunReaderOpts)
dbFromBun, err := bunReader.ReadDatabase()
require.NoError(t, err, "Failed to read Bun Go code")
require.NotNil(t, dbFromBun, "Database from Bun should not be nil")
t.Logf(" ✓ Read database from Bun with %d schemas", len(dbFromBun.Schemas))
// Step 4: Write back to YAML
t.Log("Step 4: Writing back to YAML...")
yaml2Path := filepath.Join(testDir, "roundtrip.yaml")
yamlWriter2Opts := &writers.WriterOptions{
OutputPath: yaml2Path,
}
yamlWriter2 := yamlwriter.NewWriter(yamlWriter2Opts)
err = yamlWriter2.WriteDatabase(dbFromBun)
require.NoError(t, err, "Failed to write YAML")
yaml2Stat, err := os.Stat(yaml2Path)
require.NoError(t, err, "Second YAML file should exist")
require.Greater(t, yaml2Stat.Size(), int64(0), "Second YAML file should not be empty")
t.Logf(" ✓ Wrote second YAML file (%d bytes)", yaml2Stat.Size())
// Step 5: Compare YAML files
t.Log("Step 5: Comparing YAML outputs...")
// Read both YAML files
yaml1Data, err := os.ReadFile(yamlPath)
require.NoError(t, err, "Failed to read first YAML")
yaml2Data, err := os.ReadFile(yaml2Path)
require.NoError(t, err, "Failed to read second YAML")
// Parse into Database models for comparison
var db1, db2 models.Database
err = yaml.Unmarshal(yaml1Data, &db1)
require.NoError(t, err, "Failed to parse first YAML")
err = yaml.Unmarshal(yaml2Data, &db2)
require.NoError(t, err, "Failed to parse second YAML")
// Compare high-level structure
t.Log(" Comparing high-level structure...")
assert.Equal(t, len(db1.Schemas), len(db2.Schemas), "Schema count should match")
// Compare schemas and tables
for i, schema1 := range db1.Schemas {
if i >= len(db2.Schemas) {
t.Errorf("Schema index %d out of bounds in second database", i)
continue
}
schema2 := db2.Schemas[i]
assert.Equal(t, schema1.Name, schema2.Name, "Schema names should match")
assert.Equal(t, len(schema1.Tables), len(schema2.Tables),
"Table count in schema '%s' should match", schema1.Name)
// Compare tables
for j, table1 := range schema1.Tables {
if j >= len(schema2.Tables) {
t.Errorf("Table index %d out of bounds in schema '%s'", j, schema1.Name)
continue
}
table2 := schema2.Tables[j]
assert.Equal(t, table1.Name, table2.Name,
"Table names should match in schema '%s'", schema1.Name)
// Compare column count
assert.Equal(t, len(table1.Columns), len(table2.Columns),
"Column count in table '%s.%s' should match", schema1.Name, table1.Name)
// Compare each column
for colName, col1 := range table1.Columns {
col2, ok := table2.Columns[colName]
if !ok {
t.Errorf("Column '%s' missing from roundtrip table '%s.%s'",
colName, schema1.Name, table1.Name)
continue
}
// Compare key column properties
assert.Equal(t, col1.Name, col2.Name,
"Column name mismatch in '%s.%s.%s'", schema1.Name, table1.Name, colName)
assert.Equal(t, col1.Type, col2.Type,
"Column type mismatch in '%s.%s.%s'", schema1.Name, table1.Name, colName)
assert.Equal(t, col1.IsPrimaryKey, col2.IsPrimaryKey,
"Primary key mismatch in '%s.%s.%s'", schema1.Name, table1.Name, colName)
}
}
}
// Summary
t.Log("Summary:")
t.Logf(" ✓ Round-trip completed: YAML → Bun → YAML")
t.Logf(" ✓ Schemas match: %d", len(db1.Schemas))
totalTables := 0
for _, schema := range db1.Schemas {
totalTables += len(schema.Tables)
}
t.Logf(" ✓ Total tables: %d", totalTables)
}
// TestYAMLToGORMRoundTrip tests YAML → GORM Go → YAML roundtrip
func TestYAMLToGORMRoundTrip(t *testing.T) {
testDir := t.TempDir()
// Step 1: Read YAML file
t.Log("Step 1: Reading YAML file...")
yamlPath := filepath.Join("..", "assets", "yaml", "database.yaml")
yamlReaderOpts := &readers.ReaderOptions{
FilePath: yamlPath,
}
yamlReader := yamlreader.NewReader(yamlReaderOpts)
dbFromYAML, err := yamlReader.ReadDatabase()
require.NoError(t, err, "Failed to read YAML file")
require.NotNil(t, dbFromYAML, "Database from YAML should not be nil")
t.Logf(" ✓ Read database '%s' with %d schemas", dbFromYAML.Name, len(dbFromYAML.Schemas))
// Step 2: Write to GORM Go code
t.Log("Step 2: Writing to GORM Go code...")
gormGoPath := filepath.Join(testDir, "models_gorm.go")
gormWriterOpts := &writers.WriterOptions{
OutputPath: gormGoPath,
PackageName: "models",
Metadata: map[string]interface{}{
"generate_table_name": true,
"generate_get_id": false,
},
}
gormWriter := gormwriter.NewWriter(gormWriterOpts)
err = gormWriter.WriteDatabase(dbFromYAML)
require.NoError(t, err, "Failed to write GORM Go code")
gormStat, err := os.Stat(gormGoPath)
require.NoError(t, err, "GORM Go file should exist")
require.Greater(t, gormStat.Size(), int64(0), "GORM Go file should not be empty")
t.Logf(" ✓ Wrote GORM Go file (%d bytes)", gormStat.Size())
// Step 3: Read GORM Go code back
t.Log("Step 3: Reading GORM Go code back...")
gormReaderOpts := &readers.ReaderOptions{
FilePath: gormGoPath,
}
gormReader := gormreader.NewReader(gormReaderOpts)
dbFromGORM, err := gormReader.ReadDatabase()
require.NoError(t, err, "Failed to read GORM Go code")
require.NotNil(t, dbFromGORM, "Database from GORM should not be nil")
t.Logf(" ✓ Read database from GORM with %d schemas", len(dbFromGORM.Schemas))
// Step 4: Write back to YAML
t.Log("Step 4: Writing back to YAML...")
yaml2Path := filepath.Join(testDir, "roundtrip.yaml")
yamlWriter2Opts := &writers.WriterOptions{
OutputPath: yaml2Path,
}
yamlWriter2 := yamlwriter.NewWriter(yamlWriter2Opts)
err = yamlWriter2.WriteDatabase(dbFromGORM)
require.NoError(t, err, "Failed to write YAML")
yaml2Stat, err := os.Stat(yaml2Path)
require.NoError(t, err, "Second YAML file should exist")
require.Greater(t, yaml2Stat.Size(), int64(0), "Second YAML file should not be empty")
t.Logf(" ✓ Wrote second YAML file (%d bytes)", yaml2Stat.Size())
// Step 5: Compare YAML files
t.Log("Step 5: Comparing YAML outputs...")
// Read both YAML files
yaml1Data, err := os.ReadFile(yamlPath)
require.NoError(t, err, "Failed to read first YAML")
yaml2Data, err := os.ReadFile(yaml2Path)
require.NoError(t, err, "Failed to read second YAML")
// Parse into Database models for comparison
var db1, db2 models.Database
err = yaml.Unmarshal(yaml1Data, &db1)
require.NoError(t, err, "Failed to parse first YAML")
err = yaml.Unmarshal(yaml2Data, &db2)
require.NoError(t, err, "Failed to parse second YAML")
// Compare high-level structure
t.Log(" Comparing high-level structure...")
assert.Equal(t, len(db1.Schemas), len(db2.Schemas), "Schema count should match")
// Compare schemas and tables
for i, schema1 := range db1.Schemas {
if i >= len(db2.Schemas) {
t.Errorf("Schema index %d out of bounds in second database", i)
continue
}
schema2 := db2.Schemas[i]
assert.Equal(t, schema1.Name, schema2.Name, "Schema names should match")
assert.Equal(t, len(schema1.Tables), len(schema2.Tables),
"Table count in schema '%s' should match", schema1.Name)
// Compare tables
for j, table1 := range schema1.Tables {
if j >= len(schema2.Tables) {
t.Errorf("Table index %d out of bounds in schema '%s'", j, schema1.Name)
continue
}
table2 := schema2.Tables[j]
assert.Equal(t, table1.Name, table2.Name,
"Table names should match in schema '%s'", schema1.Name)
// Compare column count
assert.Equal(t, len(table1.Columns), len(table2.Columns),
"Column count in table '%s.%s' should match", schema1.Name, table1.Name)
// Compare each column
for colName, col1 := range table1.Columns {
col2, ok := table2.Columns[colName]
if !ok {
t.Errorf("Column '%s' missing from roundtrip table '%s.%s'",
colName, schema1.Name, table1.Name)
continue
}
// Compare key column properties
assert.Equal(t, col1.Name, col2.Name,
"Column name mismatch in '%s.%s.%s'", schema1.Name, table1.Name, colName)
assert.Equal(t, col1.Type, col2.Type,
"Column type mismatch in '%s.%s.%s'", schema1.Name, table1.Name, colName)
assert.Equal(t, col1.IsPrimaryKey, col2.IsPrimaryKey,
"Primary key mismatch in '%s.%s.%s'", schema1.Name, table1.Name, colName)
}
}
}
// Summary
t.Log("Summary:")
t.Logf(" ✓ Round-trip completed: YAML → GORM → YAML")
t.Logf(" ✓ Schemas match: %d", len(db1.Schemas))
totalTables := 0
for _, schema := range db1.Schemas {
totalTables += len(schema.Tables)
}
t.Logf(" ✓ Total tables: %d", totalTables)
}