Files
relspecgo/pkg/readers/dctx/reader_test.go
Hein a427aa5537
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
More Roundtrip tests
2025-12-17 22:52:24 +02:00

496 lines
12 KiB
Go

package dctx
import (
"path/filepath"
"testing"
"git.warky.dev/wdevs/relspecgo/pkg/models"
"git.warky.dev/wdevs/relspecgo/pkg/readers"
)
func TestReader_ReadDatabase(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
db, err := reader.ReadDatabase()
if err != nil {
t.Fatalf("ReadDatabase() error = %v", err)
}
if db == nil {
t.Fatal("ReadDatabase() returned nil database")
}
if db.Name == "" {
t.Error("Expected non-empty database name")
}
if len(db.Schemas) == 0 {
t.Fatal("Expected at least one schema")
}
schema := db.Schemas[0]
if schema.Name == "" {
t.Error("Expected non-empty schema name")
}
if len(schema.Tables) == 0 {
t.Fatal("Expected at least one table")
}
// Verify at least one table has columns
hasColumns := false
for _, table := range schema.Tables {
if len(table.Columns) > 0 {
hasColumns = true
break
}
}
if !hasColumns {
t.Error("Expected at least one table with columns")
}
// Verify at least one table has a primary key
hasPK := false
for _, table := range schema.Tables {
pk := table.GetPrimaryKey()
if pk != nil {
hasPK = true
break
}
}
if !hasPK {
t.Error("Expected at least one table with a primary key")
}
// Verify at least one foreign key relationship exists
hasFKs := false
for _, table := range schema.Tables {
fks := table.GetForeignKeys()
if len(fks) > 0 {
hasFKs = true
// Verify foreign key properties
for _, fk := range fks {
if fk.Type != models.ForeignKeyConstraint {
t.Error("Expected foreign key constraint type")
}
if len(fk.Columns) == 0 {
t.Error("Foreign key should have at least one column")
}
if fk.ReferencedTable == "" {
t.Error("Foreign key should have referenced table")
}
if len(fk.ReferencedColumns) == 0 {
t.Error("Foreign key should have at least one referenced column")
}
}
break
}
}
if !hasFKs {
t.Error("Expected at least one foreign key relationship")
}
// Verify indexes exist on some tables
hasIndexes := false
for _, table := range schema.Tables {
if len(table.Indexes) > 0 {
hasIndexes = true
// Verify index properties
for _, idx := range table.Indexes {
if idx.Name == "" {
t.Error("Index should have a name")
}
if len(idx.Columns) == 0 {
t.Error("Index should have at least one column")
}
}
break
}
}
if !hasIndexes {
t.Error("Expected at least one table with indexes")
}
}
func TestReader_ReadSchema(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
schema, err := reader.ReadSchema()
if err != nil {
t.Fatalf("ReadSchema() error = %v", err)
}
if schema == nil {
t.Fatal("ReadSchema() returned nil schema")
}
if schema.Name == "" {
t.Error("Expected non-empty schema name")
}
if len(schema.Tables) == 0 {
t.Fatal("Expected at least one table")
}
}
func TestReader_ReadTable(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
table, err := reader.ReadTable()
if err != nil {
t.Fatalf("ReadTable() error = %v", err)
}
if table == nil {
t.Fatal("ReadTable() returned nil table")
}
if table.Name == "" {
t.Error("Expected non-empty table name")
}
if table.Schema == "" {
t.Error("Expected non-empty schema name")
}
if len(table.Columns) == 0 {
t.Error("Expected at least one column")
}
// Verify column properties
for _, col := range table.Columns {
if col.Name == "" {
t.Error("Column should have a name")
}
if col.Type == "" {
t.Error("Column should have a type")
}
if col.Table != table.Name {
t.Errorf("Column table '%s' should match table name '%s'", col.Table, table.Name)
}
if col.Schema != table.Schema {
t.Errorf("Column schema '%s' should match table schema '%s'", col.Schema, table.Schema)
}
}
}
func TestReader_ReadDatabase_InvalidPath(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: "/nonexistent/file.dctx",
}
reader := NewReader(opts)
_, err := reader.ReadDatabase()
if err == nil {
t.Error("Expected error for invalid file path")
}
}
func TestReader_ReadDatabase_EmptyPath(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: "",
}
reader := NewReader(opts)
_, err := reader.ReadDatabase()
if err == nil {
t.Error("Expected error for empty file path")
}
}
func TestReader_ReadSchema_EmptyPath(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: "",
}
reader := NewReader(opts)
_, err := reader.ReadSchema()
if err == nil {
t.Error("Expected error for empty file path")
}
}
func TestReader_ReadTable_EmptyPath(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: "",
}
reader := NewReader(opts)
_, err := reader.ReadTable()
if err == nil {
t.Error("Expected error for empty file path")
}
}
func TestGetPrimaryKey(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
db, err := reader.ReadDatabase()
if err != nil {
t.Fatalf("ReadDatabase() error = %v", err)
}
// Find a table with a primary key
var tableName string
var pk *models.Column
for _, schema := range db.Schemas {
for _, table := range schema.Tables {
pk = table.GetPrimaryKey()
if pk != nil {
tableName = table.Name
break
}
}
if pk != nil {
break
}
}
if pk == nil {
t.Fatal("Expected to find at least one table with a primary key")
}
if pk.Name == "" {
t.Error("Primary key should have a name")
}
if !pk.IsPrimaryKey {
t.Error("Primary key column should have IsPrimaryKey set to true")
}
t.Logf("Found primary key '%s' in table '%s'", pk.Name, tableName)
}
func TestGetForeignKeys(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
db, err := reader.ReadDatabase()
if err != nil {
t.Fatalf("ReadDatabase() error = %v", err)
}
// Find a table with foreign keys
var tableName string
var fks []*models.Constraint
for _, schema := range db.Schemas {
for _, table := range schema.Tables {
fks = table.GetForeignKeys()
if len(fks) > 0 {
tableName = table.Name
break
}
}
if len(fks) > 0 {
break
}
}
if len(fks) == 0 {
t.Fatal("Expected to find at least one table with foreign keys")
}
t.Logf("Found %d foreign keys in table '%s'", len(fks), tableName)
// Verify foreign key structure
for i, fk := range fks {
if fk.Type != models.ForeignKeyConstraint {
t.Errorf("FK %d: Expected foreign key constraint type", i)
}
if fk.Name == "" {
t.Errorf("FK %d: Expected foreign key to have a name", i)
}
if len(fk.Columns) == 0 {
t.Errorf("FK %d: Expected foreign key to have at least one column", i)
}
if fk.ReferencedTable == "" {
t.Errorf("FK %d: Expected foreign key to have a referenced table", i)
}
if len(fk.ReferencedColumns) == 0 {
t.Errorf("FK %d: Expected foreign key to have at least one referenced column", i)
}
t.Logf("FK %d: %s.%s -> %s.%s",
i,
tableName,
fk.Columns,
fk.ReferencedTable,
fk.ReferencedColumns,
)
}
}
func TestDatabaseStructure(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
db, err := reader.ReadDatabase()
if err != nil {
t.Fatalf("ReadDatabase() error = %v", err)
}
// Comprehensive structure validation
for _, schema := range db.Schemas {
if schema.Name == "" {
t.Error("Schema should have a name")
}
for _, table := range schema.Tables {
if table.Name == "" {
t.Error("Table should have a name")
}
if table.Schema == "" {
t.Error("Table should have a schema")
}
// Verify columns
for _, col := range table.Columns {
if col.Name == "" {
t.Errorf("Column in table '%s' should have a name", table.Name)
}
if col.Type == "" {
t.Errorf("Column '%s' in table '%s' should have a type", col.Name, table.Name)
}
if col.Table != table.Name {
t.Errorf("Column '%s' table reference should match table name", col.Name)
}
if col.Schema != table.Schema {
t.Errorf("Column '%s' schema reference should match table schema", col.Name)
}
}
// Verify constraints
for _, constraint := range table.Constraints {
if constraint.Name == "" {
t.Errorf("Constraint in table '%s' should have a name", table.Name)
}
if constraint.Type == "" {
t.Errorf("Constraint '%s' should have a type", constraint.Name)
}
if constraint.Table != table.Name {
t.Errorf("Constraint '%s' table reference should match table name", constraint.Name)
}
}
// Verify indexes
for _, index := range table.Indexes {
if index.Name == "" {
t.Errorf("Index in table '%s' should have a name", table.Name)
}
if len(index.Columns) == 0 {
t.Errorf("Index '%s' should have at least one column", index.Name)
}
if index.Table != table.Name {
t.Errorf("Index '%s' table reference should match table name", index.Name)
}
}
}
}
}
func TestColumnProperties(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
db, err := reader.ReadDatabase()
if err != nil {
t.Fatalf("ReadDatabase() error = %v", err)
}
// Find various column types
hasNotNullColumn := false
hasNullableColumn := false
hasDefaultValue := false
for _, schema := range db.Schemas {
for _, table := range schema.Tables {
for _, col := range table.Columns {
if col.NotNull {
hasNotNullColumn = true
} else {
hasNullableColumn = true
}
if col.Default != nil {
hasDefaultValue = true
}
}
}
}
if !hasNotNullColumn {
t.Log("Note: No NOT NULL columns found (this may be valid for the test data)")
}
if !hasNullableColumn {
t.Log("Note: No nullable columns found (this may be valid for the test data)")
}
if !hasDefaultValue {
t.Log("Note: No columns with default values found (this may be valid for the test data)")
}
}
func TestRelationships(t *testing.T) {
opts := &readers.ReaderOptions{
FilePath: filepath.Join("..", "..", "..", "examples", "dctx", "example.dctx"),
}
reader := NewReader(opts)
db, err := reader.ReadDatabase()
if err != nil {
t.Fatalf("ReadDatabase() error = %v", err)
}
// Count total relationships across all tables
relationshipCount := 0
for _, schema := range db.Schemas {
for _, table := range schema.Tables {
relationshipCount += len(table.Relationships)
}
}
// The example.dctx file should have a significant number of relationships
// With the fix for nested field GUID mapping, we expect around 100+ relationships
if relationshipCount < 50 {
t.Errorf("Expected at least 50 relationships, got %d. This may indicate relationships are not being parsed correctly", relationshipCount)
}
t.Logf("Successfully parsed %d relationships", relationshipCount)
// Verify relationship properties
for _, schema := range db.Schemas {
for _, table := range schema.Tables {
for _, rel := range table.Relationships {
if rel.Name == "" {
t.Errorf("Relationship in table '%s' should have a name", table.Name)
}
if rel.FromTable == "" {
t.Errorf("Relationship '%s' should have a from table", rel.Name)
}
if rel.ToTable == "" {
t.Errorf("Relationship '%s' should have a to table", rel.Name)
}
if rel.ForeignKey == "" {
t.Errorf("Relationship '%s' should reference a foreign key", rel.Name)
}
}
}
}
}