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  }