From 2aabe09f5c064a07dab74dcf240ab2fa51cf44db Mon Sep 17 00:00:00 2001 From: Harshit Date: Tue, 2 Sep 2025 10:05:58 +0000 Subject: [PATCH 1/3] Add tests for joins --- tests/joins_table_test.go | 57 +++++++++++++++++++++++++ tests/joins_test.go | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) diff --git a/tests/joins_table_test.go b/tests/joins_table_test.go index 4bccab2..c72caed 100644 --- a/tests/joins_table_test.go +++ b/tests/joins_table_test.go @@ -152,3 +152,60 @@ func TestOverrideJoinTable(t *testing.T) { t.Errorf("person's addresses expects 2, got %v", count) } } + +func TestOverrideJoinTableInvalidAssociation(t *testing.T) { + DB.Migrator().DropTable(&Person{}, &Address{}, &PersonAddress{}) + if err := DB.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{}); err != nil { + t.Fatalf("Failed to setup join table for person, got error %v", err) + } + if err := DB.AutoMigrate(&Person{}, &Address{}); err != nil { + t.Fatalf("Failed to migrate, got %v", err) + } + + person := Person{Name: "invalid-assoc"} + DB.Create(&person) + + err := DB.Model(&person).Association("NonExistent").Find(&[]Address{}) + if err == nil { + t.Fatalf("Expected error when accessing non-existent association, got nil") + } +} + +func TestOverrideJoinTableClearWithoutAssociations(t *testing.T) { + DB.Migrator().DropTable(&Person{}, &Address{}, &PersonAddress{}) + if err := DB.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{}); err != nil { + t.Fatalf("Failed to setup join table for person, got error %v", err) + } + if err := DB.AutoMigrate(&Person{}, &Address{}); err != nil { + t.Fatalf("Failed to migrate, got %v", err) + } + + person := Person{Name: "no-assoc"} + DB.Create(&person) + + if err := DB.Model(&person).Association("Addresses").Clear(); err != nil { + t.Fatalf("Expected no error clearing empty associations, got %v", err) + } + + if count := DB.Model(&person).Association("Addresses").Count(); count != 0 { + t.Fatalf("Expected 0 associations, got %v", count) + } +} + +func TestOverrideJoinTableDeleteNonExistentAssociation(t *testing.T) { + DB.Migrator().DropTable(&Person{}, &Address{}, &PersonAddress{}) + if err := DB.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{}); err != nil { + t.Fatalf("Failed to setup join table for person, got error %v", err) + } + if err := DB.AutoMigrate(&Person{}, &Address{}); err != nil { + t.Fatalf("Failed to migrate, got %v", err) + } + + address := Address{Name: "non-existent"} + person := Person{Name: "test-delete"} + DB.Create(&person) + + if err := DB.Model(&person).Association("Addresses").Delete(&address); err != nil { + t.Fatalf("Expected no error when deleting non-existent association, got %v", err) + } +} diff --git a/tests/joins_test.go b/tests/joins_test.go index 09e81cc..e4d8c80 100644 --- a/tests/joins_test.go +++ b/tests/joins_test.go @@ -516,3 +516,90 @@ func TestJoinsPreload_Issue7013_NoEntries(t *testing.T) { tests.AssertEqual(t, len(entries), 0) } + +type JoinCompany struct { + ID int64 `gorm:"column:id;primaryKey"` + Name string `gorm:"column:name"` +} + +type JoinUser struct { + ID int64 `gorm:"column:id;primaryKey"` + Name string `gorm:"column:name"` + CompanyID int64 `gorm:"column:company_id"` + Company JoinCompany `gorm:"foreignKey:CompanyID"` +} + +func TestJoinWithOrderLimit(t *testing.T) { + _ = DB.Migrator().DropTable(&JoinUser{}, &JoinCompany{}) + if err := DB.Migrator().CreateTable(&JoinCompany{}, &JoinUser{}); err != nil { + t.Fatalf("failed to create tables: %v", err) + } + + company := JoinCompany{Name: "TestCompany"} + if err := DB.Create(&company).Error; err != nil { + t.Fatalf("failed to insert company: %v", err) + } + + users := []JoinUser{ + {Name: "order-limit-1", CompanyID: company.ID}, + {Name: "order-limit-2", CompanyID: company.ID}, + } + if err := DB.Create(&users).Error; err != nil { + t.Fatalf("failed to insert users: %v", err) + } + + var result []JoinUser + err := DB. + Joins("Company"). + Order("\"join_users\".\"id\" DESC"). + Limit(1). + Find(&result).Error + + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(result) != 1 { + t.Errorf("expected 1 result with limit, got %d", len(result)) + } +} + +func TestJoinOnNilDB(t *testing.T) { + var users []JoinUser + var nilDB *gorm.DB + + defer func() { + if r := recover(); r == nil { + t.Errorf("expected panic when calling Joins on nil DB, got none") + } + }() + + nilDB.Joins("Company").Find(&users) +} + +func TestJoinNonExistentRelation(t *testing.T) { + var user JoinUser + err := DB.Joins("NonExistentRelation").First(&user).Error + if err == nil { + t.Errorf("expected error when joining on non-existent relation, got nil") + } +} + +func TestJoinAmbiguousColumnError(t *testing.T) { + var result []JoinUser + err := DB.Table("join_users"). + Select("id"). // ambiguous since multiple tables have id + Joins("join companies on companies.id = join_users.company_id"). + Scan(&result).Error + + if err == nil { + t.Errorf("expected error for ambiguous column selection, got nil") + } +} + +func TestJoinInvalidSQL(t *testing.T) { + var users []JoinUser + err := DB.Joins("LEFT JOIN invalid_table ON").Find(&users).Error + if err == nil { + t.Errorf("expected SQL error for invalid join, got nil") + } +} From 50bb72f8952c57f72cf6de31c2e661e3e7be5579 Mon Sep 17 00:00:00 2001 From: Harshit Date: Tue, 2 Sep 2025 10:24:20 +0000 Subject: [PATCH 2/3] Avoid Dropping table --- tests/joins_table_test.go | 3 --- tests/run-tests.sh | 18 +++--------------- tests/tests_test.go | 29 +++-------------------------- 3 files changed, 6 insertions(+), 44 deletions(-) diff --git a/tests/joins_table_test.go b/tests/joins_table_test.go index c72caed..b2aca99 100644 --- a/tests/joins_table_test.go +++ b/tests/joins_table_test.go @@ -154,7 +154,6 @@ func TestOverrideJoinTable(t *testing.T) { } func TestOverrideJoinTableInvalidAssociation(t *testing.T) { - DB.Migrator().DropTable(&Person{}, &Address{}, &PersonAddress{}) if err := DB.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{}); err != nil { t.Fatalf("Failed to setup join table for person, got error %v", err) } @@ -172,7 +171,6 @@ func TestOverrideJoinTableInvalidAssociation(t *testing.T) { } func TestOverrideJoinTableClearWithoutAssociations(t *testing.T) { - DB.Migrator().DropTable(&Person{}, &Address{}, &PersonAddress{}) if err := DB.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{}); err != nil { t.Fatalf("Failed to setup join table for person, got error %v", err) } @@ -193,7 +191,6 @@ func TestOverrideJoinTableClearWithoutAssociations(t *testing.T) { } func TestOverrideJoinTableDeleteNonExistentAssociation(t *testing.T) { - DB.Migrator().DropTable(&Person{}, &Address{}, &PersonAddress{}) if err := DB.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{}); err != nil { t.Fatalf("Failed to setup join table for person, got error %v", err) } diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 6cbe55a..38fba02 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -10,21 +10,9 @@ # 2. Run the script ./run_tests.sh # Check for required Oracle environment variables -missing_vars=() -for var in GORM_ORACLEDB_USER GORM_ORACLEDB_PASSWORD GORM_ORACLEDB_CONNECTSTRING GORM_ORACLEDB_LIBDIR; do - if [ -z "${!var}" ]; then - missing_vars+=("$var") - fi -done -if [ ${#missing_vars[@]} -ne 0 ]; then - echo "Error: The following environment variables must be set to run the tests: ${missing_vars[*]}" - echo "Example:" - echo " export GORM_ORACLEDB_USER=your_user" - echo " export GORM_ORACLEDB_PASSWORD=your_password" - echo " export GORM_ORACLEDB_CONNECTSTRING=your_connect_string" - echo " export GORM_ORACLEDB_LIBDIR=your_lib_dir" - exit 1 -fi +export GORM_DSN='user="system" password="manager" \ +connectString="phoenix808593.dev3sub4phx.databasede3phx.oraclevcn.com:1661/cdb1_pdb1.regress.rdbms.dev.us.oracle.com" \ +libDir="/home/hkhasnis/projects/pkgs/23IC"' # Check if passed-tests.txt exists if [ ! -f "passed-tests.txt" ]; then diff --git a/tests/tests_test.go b/tests/tests_test.go index 2842c83..22b082e 100644 --- a/tests/tests_test.go +++ b/tests/tests_test.go @@ -65,32 +65,9 @@ var newLogger = logger.New( }, ) -var oracleDSN = func() string { - user := os.Getenv("GORM_ORACLEDB_USER") - password := os.Getenv("GORM_ORACLEDB_PASSWORD") - connectString := os.Getenv("GORM_ORACLEDB_CONNECTSTRING") - libDir := os.Getenv("GORM_ORACLEDB_LIBDIR") - - missing := []string{} - if user == "" { - missing = append(missing, "GORM_ORACLEDB_USER") - } - if password == "" { - missing = append(missing, "GORM_ORACLEDB_PASSWORD") - } - if connectString == "" { - missing = append(missing, "GORM_ORACLEDB_CONNECTSTRING") - } - if libDir == "" { - missing = append(missing, "GORM_ORACLEDB_LIBDIR") - } - if len(missing) > 0 { - log.Fatalf("Missing required environment variables: %v. Please set them to run the tests.", missing) - } - return `user="` + user + `" password="` + password + `" - connectString="` + connectString + `" - libDir="` + libDir + `"` -}() +var oracleDSN = `user="system" password="manager" + connectString="phoenix808593.dev3sub4phx.databasede3phx.oraclevcn.com:1661/cdb1_pdb1.regress.rdbms.dev.us.oracle.com" + libDir="/home/hkhasnis/projects/pkgs/23IC"` func init() { var err error From b9dc6ee05db8f393ed7ed4fdb4e73f89d06f228a Mon Sep 17 00:00:00 2001 From: Harshit Date: Tue, 2 Sep 2025 10:25:04 +0000 Subject: [PATCH 3/3] Remove hard-coded connectionstring values --- tests/run-tests.sh | 18 +++++++++++++++--- tests/tests_test.go | 29 ++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 38fba02..6cbe55a 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -10,9 +10,21 @@ # 2. Run the script ./run_tests.sh # Check for required Oracle environment variables -export GORM_DSN='user="system" password="manager" \ -connectString="phoenix808593.dev3sub4phx.databasede3phx.oraclevcn.com:1661/cdb1_pdb1.regress.rdbms.dev.us.oracle.com" \ -libDir="/home/hkhasnis/projects/pkgs/23IC"' +missing_vars=() +for var in GORM_ORACLEDB_USER GORM_ORACLEDB_PASSWORD GORM_ORACLEDB_CONNECTSTRING GORM_ORACLEDB_LIBDIR; do + if [ -z "${!var}" ]; then + missing_vars+=("$var") + fi +done +if [ ${#missing_vars[@]} -ne 0 ]; then + echo "Error: The following environment variables must be set to run the tests: ${missing_vars[*]}" + echo "Example:" + echo " export GORM_ORACLEDB_USER=your_user" + echo " export GORM_ORACLEDB_PASSWORD=your_password" + echo " export GORM_ORACLEDB_CONNECTSTRING=your_connect_string" + echo " export GORM_ORACLEDB_LIBDIR=your_lib_dir" + exit 1 +fi # Check if passed-tests.txt exists if [ ! -f "passed-tests.txt" ]; then diff --git a/tests/tests_test.go b/tests/tests_test.go index 22b082e..2842c83 100644 --- a/tests/tests_test.go +++ b/tests/tests_test.go @@ -65,9 +65,32 @@ var newLogger = logger.New( }, ) -var oracleDSN = `user="system" password="manager" - connectString="phoenix808593.dev3sub4phx.databasede3phx.oraclevcn.com:1661/cdb1_pdb1.regress.rdbms.dev.us.oracle.com" - libDir="/home/hkhasnis/projects/pkgs/23IC"` +var oracleDSN = func() string { + user := os.Getenv("GORM_ORACLEDB_USER") + password := os.Getenv("GORM_ORACLEDB_PASSWORD") + connectString := os.Getenv("GORM_ORACLEDB_CONNECTSTRING") + libDir := os.Getenv("GORM_ORACLEDB_LIBDIR") + + missing := []string{} + if user == "" { + missing = append(missing, "GORM_ORACLEDB_USER") + } + if password == "" { + missing = append(missing, "GORM_ORACLEDB_PASSWORD") + } + if connectString == "" { + missing = append(missing, "GORM_ORACLEDB_CONNECTSTRING") + } + if libDir == "" { + missing = append(missing, "GORM_ORACLEDB_LIBDIR") + } + if len(missing) > 0 { + log.Fatalf("Missing required environment variables: %v. Please set them to run the tests.", missing) + } + return `user="` + user + `" password="` + password + `" + connectString="` + connectString + `" + libDir="` + libDir + `"` +}() func init() { var err error