Add more tests to ksql.Query()

pull/29/head
Vinícius Garcia 2022-08-27 12:16:46 -03:00
parent 74cb87bea0
commit 4b37adc905
3 changed files with 132 additions and 4 deletions

View File

@ -93,11 +93,11 @@ func GetTagInfo(key reflect.Type) (StructInfo, error) {
func getCachedTagInfo(tagInfoCache *sync.Map, key reflect.Type) (StructInfo, error) {
if data, found := tagInfoCache.Load(key); found {
if info, ok := data.(StructInfo); !ok {
info, ok := data.(StructInfo)
if !ok {
return StructInfo{}, fmt.Errorf("invalid cache entry, expected type StructInfo, found %T", data)
} else {
return info, nil
}
return info, nil
}
info, err := getTagNames(key)

View File

@ -1,6 +1,8 @@
package ksql
import "context"
import (
"context"
)
// mockTxBeginner mocks the ksql.TxBeginner interface
type mockTxBeginner struct {
@ -26,6 +28,40 @@ func (m mockDBAdapter) QueryContext(ctx context.Context, query string, args ...i
return m.QueryContextFn(ctx, query, args...)
}
type mockRows struct {
ScanFn func(...interface{}) error
CloseFn func() error
NextFn func() bool
ErrFn func() error
ColumnsFn func() ([]string, error)
}
func (m mockRows) Scan(values ...interface{}) error {
return m.ScanFn(values...)
}
func (m mockRows) Close() error {
if m.CloseFn == nil {
return nil
}
return m.CloseFn()
}
func (m mockRows) Next() bool {
return m.NextFn()
}
func (m mockRows) Err() error {
if m.ErrFn == nil {
return nil
}
return m.ErrFn()
}
func (m mockRows) Columns() ([]string, error) {
return m.ColumnsFn()
}
// mockTx mocks the ksql.Tx interface
type mockTx struct {
DBAdapter

View File

@ -403,6 +403,23 @@ func QueryTest(
tt.AssertErrContains(t, err, "error running query")
})
t.Run("should report error if the TagInfoCache returns an error", func(t *testing.T) {
db, closer := newDBAdapter(t)
defer closer.Close()
ctx := context.Background()
c := newTestDB(db, driver)
// Provoque an error by sending an invalid struct:
var users []struct {
ID int `ksql:"id"`
// Private names cannot have ksql tags:
badPrivateField string `ksql:"name"`
}
err := c.Query(ctx, &users, `SELECT * FROM users`)
tt.AssertErrContains(t, err, "badPrivateField")
})
t.Run("should report error if using nested struct and the query starts with SELECT", func(t *testing.T) {
db, closer := newDBAdapter(t)
defer closer.Close()
@ -471,6 +488,81 @@ func QueryTest(
err := c.Query(ctx, &rows, `FROM users u JOIN posts p ON u.id = p.user_id`)
tt.AssertErrContains(t, err, "same ksql tag name", "invalid_repeated_name")
})
t.Run("should report error if DBAdapter.Scan() returns an error", func(t *testing.T) {
db := mockDBAdapter{
QueryContextFn: func(ctx context.Context, query string, args ...interface{}) (Rows, error) {
return mockRows{
ColumnsFn: func() ([]string, error) {
return []string{"id", "name", "age", "address"}, nil
},
NextFn: func() bool { return true },
ScanFn: func(values ...interface{}) error {
return errors.New("fakeScanErr")
},
}, nil
},
}
ctx := context.Background()
c := newTestDB(db, driver)
var users []user
err := c.Query(ctx, &users, `SELECT * FROM users`)
tt.AssertErrContains(t, err, "fakeScanErr")
})
t.Run("should report error if DBAdapter.Err() returns an error", func(t *testing.T) {
db := mockDBAdapter{
QueryContextFn: func(ctx context.Context, query string, args ...interface{}) (Rows, error) {
return mockRows{
ColumnsFn: func() ([]string, error) {
return []string{"id", "name", "age", "address"}, nil
},
NextFn: func() bool { return false },
ScanFn: func(values ...interface{}) error {
return nil
},
ErrFn: func() error {
return errors.New("fakeErrMsg")
},
}, nil
},
}
ctx := context.Background()
c := newTestDB(db, driver)
var users []user
err := c.Query(ctx, &users, `SELECT * FROM users`)
tt.AssertErrContains(t, err, "fakeErrMsg")
})
t.Run("should report error if DBAdapter.Close() returns an error", func(t *testing.T) {
db := mockDBAdapter{
QueryContextFn: func(ctx context.Context, query string, args ...interface{}) (Rows, error) {
return mockRows{
ColumnsFn: func() ([]string, error) {
return []string{"id", "name", "age", "address"}, nil
},
NextFn: func() bool { return false },
ScanFn: func(values ...interface{}) error {
return nil
},
CloseFn: func() error {
return errors.New("fakeCloseErr")
},
}, nil
},
}
ctx := context.Background()
c := newTestDB(db, driver)
var users []user
err := c.Query(ctx, &users, `SELECT * FROM users`)
tt.AssertErrContains(t, err, "fakeCloseErr")
})
})
})
}