package json 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("..", "..", "..", "tests", "assets", "json", "database.json"), } 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 != "test_db" { t.Errorf("Expected database name 'test_db', got '%s'", db.Name) } if db.Description != "Test database for JSON reader" { t.Errorf("Expected description 'Test database for JSON reader', got '%s'", db.Description) } if db.DatabaseType != models.PostgresqlDatabaseType { t.Errorf("Expected database type 'pgsql', got '%s'", db.DatabaseType) } if len(db.Schemas) != 1 { t.Fatalf("Expected 1 schema, got %d", len(db.Schemas)) } schema := db.Schemas[0] if schema.Name != "public" { t.Errorf("Expected schema name 'public', got '%s'", schema.Name) } if len(schema.Tables) != 2 { t.Fatalf("Expected 2 tables, got %d", len(schema.Tables)) } // Find users table var usersTable *models.Table for _, table := range schema.Tables { if table.Name == "users" { usersTable = table break } } if usersTable == nil { t.Fatal("Users table not found") } if usersTable.Description != "User accounts table" { t.Errorf("Expected table description 'User accounts table', got '%s'", usersTable.Description) } if len(usersTable.Columns) != 4 { t.Errorf("Expected 4 columns, got %d", len(usersTable.Columns)) } // Verify id column idCol, exists := usersTable.Columns["id"] if !exists { t.Fatal("Column 'id' not found") } if !idCol.IsPrimaryKey { t.Error("Column 'id' should be primary key") } if !idCol.AutoIncrement { t.Error("Column 'id' should be auto-increment") } if !idCol.NotNull { t.Error("Column 'id' should be not null") } if idCol.Type != "bigint" { t.Errorf("Expected id type 'bigint', got '%s'", idCol.Type) } // Verify email column emailCol, exists := usersTable.Columns["email"] if !exists { t.Fatal("Column 'email' not found") } if !emailCol.NotNull { t.Error("Column 'email' should be not null") } if emailCol.Type != "varchar" { t.Errorf("Expected email type 'varchar', got '%s'", emailCol.Type) } if emailCol.Length != 255 { t.Errorf("Expected email length 255, got %d", emailCol.Length) } if emailCol.Comment != "User email address" { t.Errorf("Expected email comment 'User email address', got '%s'", emailCol.Comment) } // Verify created_at column with default createdCol, exists := usersTable.Columns["created_at"] if !exists { t.Fatal("Column 'created_at' not found") } if createdCol.Default == nil { t.Error("Expected default value for created_at") } if createdCol.Default != "CURRENT_TIMESTAMP" { t.Errorf("Expected default 'CURRENT_TIMESTAMP', got '%v'", createdCol.Default) } // Verify index if len(usersTable.Indexes) != 1 { t.Errorf("Expected 1 index, got %d", len(usersTable.Indexes)) } emailIdx, exists := usersTable.Indexes["idx_users_email"] if !exists { t.Fatal("Index 'idx_users_email' not found") } if !emailIdx.Unique { t.Error("Email index should be unique") } if len(emailIdx.Columns) != 1 || emailIdx.Columns[0] != "email" { t.Error("Email index should have 'email' column") } if emailIdx.Type != "btree" { t.Errorf("Expected index type 'btree', got '%s'", emailIdx.Type) } // Find posts table and verify foreign key var postsTable *models.Table for _, table := range schema.Tables { if table.Name == "posts" { postsTable = table break } } if postsTable == nil { t.Fatal("Posts table not found") } if len(postsTable.Constraints) != 1 { t.Errorf("Expected 1 constraint, got %d", len(postsTable.Constraints)) } fk, exists := postsTable.Constraints["fk_posts_user"] if !exists { t.Fatal("Foreign key 'fk_posts_user' not found") } if fk.Type != models.ForeignKeyConstraint { t.Error("Expected foreign key constraint type") } if fk.ReferencedTable != "users" { t.Errorf("Expected referenced table 'users', got '%s'", fk.ReferencedTable) } if fk.ReferencedSchema != "public" { t.Errorf("Expected referenced schema 'public', got '%s'", fk.ReferencedSchema) } if len(fk.Columns) != 1 || fk.Columns[0] != "user_id" { t.Error("Expected FK column 'user_id'") } if len(fk.ReferencedColumns) != 1 || fk.ReferencedColumns[0] != "id" { t.Error("Expected FK referenced column 'id'") } if fk.OnDelete != "CASCADE" { t.Errorf("Expected ON DELETE CASCADE, got '%s'", fk.OnDelete) } if fk.OnUpdate != "CASCADE" { t.Errorf("Expected ON UPDATE CASCADE, got '%s'", fk.OnUpdate) } } func TestReader_ReadSchema(t *testing.T) { opts := &readers.ReaderOptions{ FilePath: filepath.Join("..", "..", "..", "tests", "assets", "json", "schema.json"), } 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 != "public" { t.Errorf("Expected schema name 'public', got '%s'", schema.Name) } if schema.Description != "Public schema" { t.Errorf("Expected description 'Public schema', got '%s'", schema.Description) } if len(schema.Tables) != 1 { t.Errorf("Expected 1 table, got %d", len(schema.Tables)) } table := schema.Tables[0] if table.Name != "users" { t.Errorf("Expected table name 'users', got '%s'", table.Name) } if len(table.Columns) != 2 { t.Errorf("Expected 2 columns, got %d", len(table.Columns)) } // Verify username column usernameCol, exists := table.Columns["username"] if !exists { t.Fatal("Column 'username' not found") } if usernameCol.Type != "varchar" { t.Errorf("Expected username type 'varchar', got '%s'", usernameCol.Type) } if usernameCol.Length != 50 { t.Errorf("Expected username length 50, got %d", usernameCol.Length) } } func TestReader_ReadTable(t *testing.T) { opts := &readers.ReaderOptions{ FilePath: filepath.Join("..", "..", "..", "tests", "assets", "json", "table.json"), } 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 != "users" { t.Errorf("Expected table name 'users', got '%s'", table.Name) } if table.Schema != "public" { t.Errorf("Expected schema 'public', got '%s'", table.Schema) } if table.Description != "Users table" { t.Errorf("Expected description 'Users table', got '%s'", table.Description) } if len(table.Columns) != 2 { t.Errorf("Expected 2 columns, got %d", len(table.Columns)) } // Verify columns idCol, exists := table.Columns["id"] if !exists { t.Fatal("Column 'id' not found") } if !idCol.IsPrimaryKey { t.Error("Column 'id' should be primary key") } emailCol, exists := table.Columns["email"] if !exists { t.Fatal("Column 'email' not found") } if emailCol.Length != 255 { t.Errorf("Expected email length 255, got %d", emailCol.Length) } } func TestReader_ReadDatabase_InvalidPath(t *testing.T) { opts := &readers.ReaderOptions{ FilePath: "/nonexistent/file.json", } 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("..", "..", "..", "tests", "assets", "json", "table.json"), } reader := NewReader(opts) table, err := reader.ReadTable() if err != nil { t.Fatalf("ReadTable() error = %v", err) } pk := table.GetPrimaryKey() if pk == nil { t.Fatal("Expected primary key, got nil") } if pk.Name != "id" { t.Errorf("Expected primary key name 'id', got '%s'", pk.Name) } } func TestGetForeignKeys(t *testing.T) { opts := &readers.ReaderOptions{ FilePath: filepath.Join("..", "..", "..", "tests", "assets", "json", "database.json"), } reader := NewReader(opts) db, err := reader.ReadDatabase() if err != nil { t.Fatalf("ReadDatabase() error = %v", err) } // Find posts table var postsTable *models.Table for _, schema := range db.Schemas { for _, table := range schema.Tables { if table.Name == "posts" { postsTable = table break } } } if postsTable == nil { t.Fatal("Posts table not found") } fks := postsTable.GetForeignKeys() if len(fks) != 1 { t.Errorf("Expected 1 foreign key, got %d", len(fks)) } if len(fks) > 0 && fks[0].Type != models.ForeignKeyConstraint { t.Error("Expected foreign key constraint type") } }