mirror of https://github.com/VinGarcia/ksql.git
Add more tests to ksql.Query()
parent
74cb87bea0
commit
4b37adc905
|
@ -93,11 +93,11 @@ func GetTagInfo(key reflect.Type) (StructInfo, error) {
|
||||||
|
|
||||||
func getCachedTagInfo(tagInfoCache *sync.Map, key reflect.Type) (StructInfo, error) {
|
func getCachedTagInfo(tagInfoCache *sync.Map, key reflect.Type) (StructInfo, error) {
|
||||||
if data, found := tagInfoCache.Load(key); found {
|
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)
|
return StructInfo{}, fmt.Errorf("invalid cache entry, expected type StructInfo, found %T", data)
|
||||||
} else {
|
|
||||||
return info, nil
|
|
||||||
}
|
}
|
||||||
|
return info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := getTagNames(key)
|
info, err := getTagNames(key)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package ksql
|
package ksql
|
||||||
|
|
||||||
import "context"
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
// mockTxBeginner mocks the ksql.TxBeginner interface
|
// mockTxBeginner mocks the ksql.TxBeginner interface
|
||||||
type mockTxBeginner struct {
|
type mockTxBeginner struct {
|
||||||
|
@ -26,6 +28,40 @@ func (m mockDBAdapter) QueryContext(ctx context.Context, query string, args ...i
|
||||||
return m.QueryContextFn(ctx, query, args...)
|
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
|
// mockTx mocks the ksql.Tx interface
|
||||||
type mockTx struct {
|
type mockTx struct {
|
||||||
DBAdapter
|
DBAdapter
|
||||||
|
|
|
@ -403,6 +403,23 @@ func QueryTest(
|
||||||
tt.AssertErrContains(t, err, "error running query")
|
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) {
|
t.Run("should report error if using nested struct and the query starts with SELECT", func(t *testing.T) {
|
||||||
db, closer := newDBAdapter(t)
|
db, closer := newDBAdapter(t)
|
||||||
defer closer.Close()
|
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`)
|
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")
|
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")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue