github.com/moznion/go-optional@v0.11.1-0.20240312043125-6881072e44c1/sql_driver_test.go (about) 1 package optional 2 3 import ( 4 "database/sql" 5 "database/sql/driver" 6 "os" 7 "testing" 8 "time" 9 10 _ "github.com/mattn/go-sqlite3" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestOption_Scan(t *testing.T) { 15 o := Some[any](nil) 16 17 err := o.Scan("bar") 18 assert.NoError(t, err) 19 assert.EqualValues(t, "bar", o.Unwrap()) 20 21 err = o.Scan([]byte("buz")) 22 assert.NoError(t, err) 23 assert.EqualValues(t, []byte("buz"), o.Unwrap()) 24 25 err = o.Scan(int64(42)) 26 assert.NoError(t, err) 27 assert.EqualValues(t, 42, o.Unwrap()) 28 29 err = o.Scan(float64(123.456)) 30 assert.NoError(t, err) 31 assert.EqualValues(t, 123.456, o.Unwrap()) 32 33 err = o.Scan(true) 34 assert.NoError(t, err) 35 assert.EqualValues(t, true, o.Unwrap()) 36 37 now := time.Now() 38 err = o.Scan(now) 39 assert.NoError(t, err) 40 assert.EqualValues(t, now, o.Unwrap()) 41 } 42 43 func TestOption_Scan_None(t *testing.T) { 44 o := Some[any](nil) 45 46 err := o.Scan(nil) 47 assert.NoError(t, err) 48 assert.True(t, o.IsNone()) 49 } 50 51 func TestOption_Scan_UnsupportedTypes(t *testing.T) { 52 type ustruct struct { 53 A int 54 } 55 56 o := Some[ustruct](ustruct{}) 57 err := o.Scan(int32(42)) 58 assert.Error(t, err) 59 } 60 61 func TestOption_Scan_ScannerInterfaceSatisfaction(t *testing.T) { 62 o := Some[any]("string") 63 var s sql.Scanner = &o 64 assert.NotNil(t, s) 65 } 66 67 func TestOption_Value(t *testing.T) { 68 { 69 o := Some[string]("foo") 70 v, err := o.Value() 71 assert.NoError(t, err) 72 assert.EqualValues(t, "foo", v) 73 } 74 75 { 76 o := Some[[]byte]([]byte("bar")) 77 v, err := o.Value() 78 assert.NoError(t, err) 79 assert.EqualValues(t, []byte("bar"), v) 80 } 81 82 { 83 o := Some[int64](42) 84 v, err := o.Value() 85 assert.NoError(t, err) 86 assert.EqualValues(t, 42, v) 87 } 88 89 { 90 o := Some[float64](123.456) 91 v, err := o.Value() 92 assert.NoError(t, err) 93 assert.EqualValues(t, 123.456, v) 94 } 95 96 { 97 o := Some[bool](true) 98 v, err := o.Value() 99 assert.NoError(t, err) 100 assert.EqualValues(t, true, v) 101 } 102 103 { 104 now := time.Now() 105 o := Some[time.Time](now) 106 v, err := o.Value() 107 assert.NoError(t, err) 108 assert.EqualValues(t, now, v) 109 } 110 } 111 112 func TestOption_Value_None(t *testing.T) { 113 o := None[string]() 114 v, err := o.Value() 115 assert.NoError(t, err) 116 assert.Nil(t, v) 117 } 118 119 func TestOption_Value_UnsupportedTypes(t *testing.T) { 120 type ustruct struct { 121 A int 122 } 123 124 o := Some[ustruct](ustruct{}) 125 _, err := o.Value() 126 assert.Error(t, err) 127 } 128 129 func TestOption_Value_ValuerInterfaceSatisfaction(t *testing.T) { 130 o := Some[any]("string") 131 var s driver.Valuer = &o 132 assert.NotNil(t, s) 133 } 134 135 func TestOption_SQLScan(t *testing.T) { 136 tmpfile, err := os.CreateTemp(os.TempDir(), "testdb") 137 assert.NoError(t, err) 138 139 db, err := sql.Open("sqlite3", tmpfile.Name()) 140 assert.NoError(t, err) 141 defer func() { 142 _ = db.Close() 143 }() 144 145 sqlStmt := "CREATE TABLE test_table (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(32));" 146 _, err = db.Exec(sqlStmt) 147 assert.NoError(t, err) 148 149 tx, err := db.Begin() 150 assert.NoError(t, err) 151 func() { 152 stmt, err := tx.Prepare("INSERT INTO test_table(id, name) values(?, ?)") 153 assert.NoError(t, err) 154 defer func() { 155 _ = stmt.Close() 156 }() 157 _, err = stmt.Exec(1, "foo") 158 assert.NoError(t, err) 159 }() 160 func() { 161 stmt, err := tx.Prepare("INSERT INTO test_table(id) values(?)") 162 assert.NoError(t, err) 163 defer func() { 164 _ = stmt.Close() 165 }() 166 _, err = stmt.Exec(2) 167 assert.NoError(t, err) 168 }() 169 err = tx.Commit() 170 assert.NoError(t, err) 171 172 var maybeName Option[string] 173 174 row := db.QueryRow("SELECT name FROM test_table WHERE id = 1") 175 err = row.Scan(&maybeName) 176 assert.NoError(t, err) 177 assert.Equal(t, "foo", maybeName.Unwrap()) 178 179 row = db.QueryRow("SELECT name FROM test_table WHERE id = 2") 180 err = row.Scan(&maybeName) 181 assert.NoError(t, err) 182 assert.True(t, maybeName.IsNone()) 183 } 184 185 func TestOption_SQLValuer(t *testing.T) { 186 tmpfile, err := os.CreateTemp(os.TempDir(), "testdb") 187 assert.NoError(t, err) 188 189 db, err := sql.Open("sqlite3", tmpfile.Name()) 190 assert.NoError(t, err) 191 defer func() { 192 _ = db.Close() 193 }() 194 195 sqlStmt := "CREATE TABLE test_table (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(32));" 196 _, err = db.Exec(sqlStmt) 197 assert.NoError(t, err) 198 199 tx, err := db.Begin() 200 assert.NoError(t, err) 201 func() { 202 stmt, err := tx.Prepare("INSERT INTO test_table(id, name) values(?, ?)") 203 assert.NoError(t, err) 204 defer func() { 205 _ = stmt.Close() 206 }() 207 _, err = stmt.Exec(1, Some[string]("foo")) 208 assert.NoError(t, err) 209 }() 210 func() { 211 stmt, err := tx.Prepare("INSERT INTO test_table(id, name) values(?, ?)") 212 assert.NoError(t, err) 213 defer func() { 214 _ = stmt.Close() 215 }() 216 _, err = stmt.Exec(2, None[string]()) 217 assert.NoError(t, err) 218 }() 219 err = tx.Commit() 220 assert.NoError(t, err) 221 222 var maybeName Option[string] 223 224 row := db.QueryRow("SELECT name FROM test_table WHERE id = 1") 225 err = row.Scan(&maybeName) 226 assert.NoError(t, err) 227 assert.Equal(t, "foo", maybeName.Unwrap()) 228 229 row = db.QueryRow("SELECT name FROM test_table WHERE id = 2") 230 err = row.Scan(&maybeName) 231 assert.NoError(t, err) 232 assert.True(t, maybeName.IsNone()) 233 }