1package sqlite_test
2
3import (
4 "path/filepath"
5 "sync"
6 "testing"
7
8 "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"
9 "github.com/stretchr/testify/assert"
10 "github.com/stretchr/testify/require"
11)
12
13func TestLazyDB_NotInitializedByDefault(t *testing.T) {
14 dbPath := filepath.Join(t.TempDir(), "test.db")
15 lazy := sqlite.NewLazyDB(dbPath)
16
17 assert.False(t, lazy.IsInitialized(), "LazyDB should not be initialized before DB() is called")
18}
19
20func TestLazyDB_InitializesOnFirstAccess(t *testing.T) {
21 ctx := testCtx()
22 dbPath := filepath.Join(t.TempDir(), "test.db")
23 lazy := sqlite.NewLazyDB(dbPath)
24
25 db, err := lazy.DB(ctx)
26 require.NoError(t, err)
27 require.NotNil(t, db)
28
29 assert.True(t, lazy.IsInitialized(), "LazyDB should be initialized after DB() is called")
30
31 // Cleanup
32 require.NoError(t, lazy.Close())
33}
34
35func TestLazyDB_ReturnsSameConnection(t *testing.T) {
36 ctx := testCtx()
37 dbPath := filepath.Join(t.TempDir(), "test.db")
38 lazy := sqlite.NewLazyDB(dbPath)
39
40 db1, err := lazy.DB(ctx)
41 require.NoError(t, err)
42
43 db2, err := lazy.DB(ctx)
44 require.NoError(t, err)
45
46 assert.Same(t, db1, db2, "DB() should return the same connection instance")
47
48 require.NoError(t, lazy.Close())
49}
50
51func TestLazyDB_ConcurrentAccess(t *testing.T) {
52 ctx := testCtx()
53 dbPath := filepath.Join(t.TempDir(), "test.db")
54 lazy := sqlite.NewLazyDB(dbPath)
55
56 const goroutines = 10
57 var wg sync.WaitGroup
58 wg.Add(goroutines)
59
60 results := make(chan *struct {
61 db any
62 err error
63 }, goroutines)
64
65 for range goroutines {
66 go func() {
67 defer wg.Done()
68 db, err := lazy.DB(ctx)
69 results <- &struct {
70 db any
71 err error
72 }{db, err}
73 }()
74 }
75
76 wg.Wait()
77 close(results)
78
79 var firstDB any
80 for result := range results {
81 require.NoError(t, result.err)
82 require.NotNil(t, result.db)
83
84 if firstDB == nil {
85 firstDB = result.db
86 } else {
87 assert.Same(t, firstDB, result.db, "All goroutines should receive the same DB instance")
88 }
89 }
90
91 require.NoError(t, lazy.Close())
92}
93
94func TestLazyDB_CloseBeforeInit(t *testing.T) {
95 dbPath := filepath.Join(t.TempDir(), "test.db")
96 lazy := sqlite.NewLazyDB(dbPath)
97
98 // Close without ever calling DB() should not error
99 err := lazy.Close()
100 assert.NoError(t, err)
101}
102
103func TestLazyDB_Path(t *testing.T) {
104 dbPath := "/some/path/to/db.sqlite"
105 lazy := sqlite.NewLazyDB(dbPath)
106
107 assert.Equal(t, dbPath, lazy.Path())
108}
109
110func TestLazyDB_DBIsUsable(t *testing.T) {
111 ctx := testCtx()
112 dbPath := filepath.Join(t.TempDir(), "test.db")
113 lazy := sqlite.NewLazyDB(dbPath)
114
115 db, err := lazy.DB(ctx)
116 require.NoError(t, err)
117
118 // Verify we can execute a simple query
119 var result int
120 err = db.QueryRowContext(ctx, "SELECT 1").Scan(&result)
121 require.NoError(t, err)
122 assert.Equal(t, 1, result)
123
124 require.NoError(t, lazy.Close())
125}