package database import ( "context" "database/sql" "testing" ) // Mock types for testing SQLC integration patterns type mockQueries struct { db DBTX } type mockQueriesTx struct { *mockQueries tx *sql.Tx } // Mock the Begin method pattern that SQLC generates func (q *mockQueries) Begin(ctx context.Context) (*mockQueriesTx, error) { // This would normally be: tx, err := q.db.(*sql.DB).BeginTx(ctx, nil) // For our test, we return a mock return &mockQueriesTx{mockQueries: q, tx: nil}, nil } func (qtx *mockQueriesTx) Commit(ctx context.Context) error { return nil // Mock implementation } func (qtx *mockQueriesTx) Rollback(ctx context.Context) error { return nil // Mock implementation } // This test verifies that our common database interfaces are compatible with SQLC-generated code func TestSQLCIntegration(t *testing.T) { // Test that SQLC's DBTX interface matches our DBTX interface t.Run("DBTX Interface Compatibility", func(t *testing.T) { // Test interface compatibility by assignment without execution var ourDBTX DBTX // Test with sql.DB (should implement DBTX) var db *sql.DB ourDBTX = db // This will compile only if interfaces are compatible _ = ourDBTX // Use the variable to avoid "unused" warning // Test with sql.Tx (should implement DBTX) var tx *sql.Tx ourDBTX = tx // This will compile only if interfaces are compatible _ = ourDBTX // Use the variable to avoid "unused" warning // If we reach here, interfaces are compatible t.Log("DBTX interface is compatible with sql.DB and sql.Tx") }) t.Run("Transaction Interface Compatibility", func(t *testing.T) { // This test verifies our transaction interfaces work with SQLC patterns // We can't define methods inside a function, so we test interface compatibility // Verify our DB interface is compatible with what SQLC expects var dbInterface DB[*mockQueriesTx] var mockDB *mockQueries = &mockQueries{} dbInterface = mockDB // Test that our transaction helper can work with this pattern err := WithTransaction(context.Background(), dbInterface, func(ctx context.Context, qtx *mockQueriesTx) error { // This would be where you'd call SQLC-generated query methods return nil }) if err != nil { t.Errorf("Transaction helper failed: %v", err) } }) } // Test that demonstrates how the common package would be used with real SQLC patterns func TestRealWorldUsagePattern(t *testing.T) { // This test shows how a package would typically use our common database code t.Run("Database Opening Pattern", func(t *testing.T) { // Test that our configuration options work as expected opts := DefaultConfigOptions() // Modify for test environment (no actual database connection) opts.ConfigFiles = []string{} // No config files for unit test opts.PrometheusRegisterer = nil // No metrics for unit test // This would normally open a database: db, err := OpenDB(ctx, opts) // For our unit test, we just verify the options are reasonable if opts.MaxOpenConns <= 0 { t.Error("MaxOpenConns should be positive") } if opts.MaxIdleConns <= 0 { t.Error("MaxIdleConns should be positive") } if opts.ConnMaxLifetime <= 0 { t.Error("ConnMaxLifetime should be positive") } }) t.Run("Monitor Package Configuration", func(t *testing.T) { opts := MonitorConfigOptions() // Verify monitor-specific settings if opts.EnablePoolMonitoring { t.Error("Monitor package should not enable pool monitoring") } if opts.PrometheusRegisterer != nil { t.Error("Monitor package should not have Prometheus registerer") } if opts.MaxOpenConns != 10 { t.Errorf("Expected MaxOpenConns=10 for monitor, got %d", opts.MaxOpenConns) } if opts.MaxIdleConns != 5 { t.Errorf("Expected MaxIdleConns=5 for monitor, got %d", opts.MaxIdleConns) } }) }