Skip to content

Commit e2789a4

Browse files
committed
Removing sqlite dependency
1 parent e69e0ed commit e2789a4

2 files changed

Lines changed: 52 additions & 29 deletions

File tree

database_interface_matching_test.go

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"testing"
88

99
"github.com/stretchr/testify/assert"
10-
"github.com/stretchr/testify/require"
11-
_ "modernc.org/sqlite" // Import pure Go SQLite driver for testing
1210
)
1311

1412
// DatabaseExecutor matches the user's interface from the problem description
@@ -23,43 +21,69 @@ type DatabaseExecutor interface {
2321
// Ensure that *sql.DB implements our interface
2422
var _ DatabaseExecutor = (*sql.DB)(nil)
2523

24+
// mockDatabaseExecutor is a mock implementation for testing
25+
type mockDatabaseExecutor struct{}
26+
27+
func (m *mockDatabaseExecutor) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
28+
return &mockResult{}, nil
29+
}
30+
31+
func (m *mockDatabaseExecutor) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
32+
return nil, nil
33+
}
34+
35+
func (m *mockDatabaseExecutor) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
36+
return &sql.Row{}
37+
}
38+
39+
func (m *mockDatabaseExecutor) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
40+
return nil, nil
41+
}
42+
43+
func (m *mockDatabaseExecutor) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
44+
return nil, nil
45+
}
46+
47+
// mockResult implements sql.Result for testing
48+
type mockResult struct{}
49+
50+
func (m *mockResult) LastInsertId() (int64, error) { return 0, nil }
51+
func (m *mockResult) RowsAffected() (int64, error) { return 0, nil }
52+
53+
// Ensure our mock implements the interface
54+
var _ DatabaseExecutor = (*mockDatabaseExecutor)(nil)
55+
2656
// MockDatabaseService simulates what the database module provides
2757
type MockDatabaseService interface {
28-
DB() *sql.DB
58+
DB() DatabaseExecutor
2959
Close() error
3060
}
3161

3262
// mockDatabaseServiceImpl simulates the lazy wrapper that the database module uses
3363
type mockDatabaseServiceImpl struct {
34-
db *sql.DB
64+
executor DatabaseExecutor
3565
}
3666

37-
func (m *mockDatabaseServiceImpl) DB() *sql.DB {
38-
return m.db
67+
func (m *mockDatabaseServiceImpl) DB() DatabaseExecutor {
68+
return m.executor
3969
}
4070

4171
func (m *mockDatabaseServiceImpl) Close() error {
42-
if m.db != nil {
43-
return m.db.Close()
44-
}
4572
return nil
4673
}
4774

4875
// TestInterfaceMatchingCore demonstrates the core issue with interface matching
4976
func TestInterfaceMatchingCore(t *testing.T) {
5077
// Create a mock database service (simulating what the database module provides)
51-
db, err := sql.Open("sqlite", ":memory:")
52-
require.NoError(t, err)
53-
defer db.Close()
54-
55-
mockService := &mockDatabaseServiceImpl{db: db}
78+
mockExecutor := &mockDatabaseExecutor{}
79+
mockService := &mockDatabaseServiceImpl{executor: mockExecutor}
5680

57-
// Test 1: Check if *sql.DB implements DatabaseExecutor (it should)
81+
// Test 1: Check if mockDatabaseExecutor implements DatabaseExecutor (it should)
5882
expectedType := reflect.TypeOf((*DatabaseExecutor)(nil)).Elem()
59-
sqlDBType := reflect.TypeOf((*sql.DB)(nil))
83+
mockExecutorType := reflect.TypeOf((*mockDatabaseExecutor)(nil))
6084

61-
assert.True(t, sqlDBType.Implements(expectedType),
62-
"*sql.DB should implement DatabaseExecutor interface")
85+
assert.True(t, mockExecutorType.Implements(expectedType),
86+
"mockDatabaseExecutor should implement DatabaseExecutor interface")
6387

6488
// Test 2: Check if mockDatabaseServiceImpl implements DatabaseExecutor (it should NOT)
6589
mockServiceType := reflect.TypeOf((*mockDatabaseServiceImpl)(nil))
@@ -71,16 +95,16 @@ func TestInterfaceMatchingCore(t *testing.T) {
7195
assert.True(t, mockServiceType.Implements(mockDBServiceType),
7296
"mockDatabaseServiceImpl should implement MockDatabaseService interface")
7397

74-
// Test 4: Demonstrate the workaround - extract the *sql.DB from the service
98+
// Test 4: Demonstrate the workaround - extract the DatabaseExecutor from the service
7599
actualDB := mockService.DB()
76100
actualDBType := reflect.TypeOf(actualDB)
77101
assert.True(t, actualDBType.Implements(expectedType),
78-
"The *sql.DB extracted from the service should implement DatabaseExecutor")
102+
"The DatabaseExecutor returned by the service should implement DatabaseExecutor")
79103

80104
t.Log("✅ Core issue demonstrated:")
81-
t.Log(" - *sql.DB implements DatabaseExecutor ✓")
105+
t.Log(" - mockDatabaseExecutor implements DatabaseExecutor ✓")
82106
t.Log(" - Database service wrapper does NOT implement DatabaseExecutor ✗")
83-
t.Log(" - But wrapper.DB() returns *sql.DB which does implement DatabaseExecutor ✓")
107+
t.Log(" - But wrapper.DB() returns DatabaseExecutor which does implement DatabaseExecutor ✓")
84108
}
85109

86110
// TestServiceDependencyMatching simulates the service dependency resolution
@@ -134,15 +158,15 @@ func (m *MockDatabaseModule) Dependencies() []string {
134158
}
135159

136160
func (m *MockDatabaseModule) ProvidesServices() []ServiceProvider {
137-
// Create a dummy *sql.DB for testing
138-
db, _ := sql.Open("sqlite", ":memory:")
139-
wrapper := &mockDatabaseServiceImpl{db: db}
161+
// Create a dummy mock executor for testing
162+
mockExecutor := &mockDatabaseExecutor{}
163+
wrapper := &mockDatabaseServiceImpl{executor: mockExecutor}
140164

141165
return []ServiceProvider{
142166
{
143167
Name: "database.service",
144168
Description: "Database service wrapper",
145-
Instance: wrapper, // Provide wrapper, not *sql.DB directly
169+
Instance: wrapper, // Provide wrapper, not direct executor
146170
},
147171
}
148172
}
@@ -154,7 +178,6 @@ func (m *MockDatabaseModule) RequiresServices() []ServiceDependency {
154178
// FailingTestModule tries to use MatchByInterface=true (will fail)
155179
type FailingTestModule struct {
156180
name string
157-
db DatabaseExecutor
158181
}
159182

160183
func (m *FailingTestModule) Name() string {

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
module github.com/GoCodeAlone/modular
22

3-
go 1.22
3+
go 1.23.0
44

5-
toolchain go1.23.9
5+
toolchain go1.24.2
66

77
require (
88
github.com/BurntSushi/toml v1.5.0

0 commit comments

Comments
 (0)