adding new functionality for mocks
- working through insert logic - ideally return struct with 'good' fields - also return list of args to prevent relooping
This commit is contained in:
17
driver.go
Normal file
17
driver.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package lazy
|
||||||
|
|
||||||
|
//driver.Result does not play well with creation, overriding it here so we can return the results without
|
||||||
|
//requiring sqlmock
|
||||||
|
type sqlResult struct {
|
||||||
|
insertID int64
|
||||||
|
rowsAffected int64
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *sqlResult) LastInsertId() (int64, error) {
|
||||||
|
return r.insertID, r.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *sqlResult) RowsAffected() (int64, error) {
|
||||||
|
return r.rowsAffected, r.err
|
||||||
|
}
|
82
lazy.go
82
lazy.go
@@ -17,29 +17,47 @@ const (
|
|||||||
KEY_VALUE = "key" //tag value for LAZY_TAG
|
KEY_VALUE = "key" //tag value for LAZY_TAG
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrBadExample = errors.New("example field must be a non-nil struct")
|
||||||
|
ErrMissingKeys = errors.New("there must be a key for each row requested with RowCount")
|
||||||
|
ErrUnsupportedType = errors.New("")
|
||||||
|
)
|
||||||
|
|
||||||
// mock data generated based on config
|
// mock data generated based on config
|
||||||
type Mock struct {
|
type RowMock struct {
|
||||||
Query string
|
Query string
|
||||||
Columns []string
|
Columns []string
|
||||||
Rows [][]driver.Value
|
Rows [][]driver.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
// configuration for RandomGenerate
|
// configuration for RandomGenerate
|
||||||
type Config struct {
|
type RowConfig struct {
|
||||||
Query string
|
Query string
|
||||||
Example any
|
Example any
|
||||||
Keys []any //length of keys must = RowCount, if set
|
Keys []any //if set, length of keys must = RowCount
|
||||||
RowCount int
|
RowCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StructMock struct {
|
||||||
|
Query string
|
||||||
|
Args []any
|
||||||
|
MockStruct any
|
||||||
|
Result driver.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
type StructConfig struct {
|
||||||
|
Query string
|
||||||
|
Example any
|
||||||
|
}
|
||||||
|
|
||||||
// generates mock data based on configuration to be used for sqlmock
|
// generates mock data based on configuration to be used for sqlmock
|
||||||
func RandomGenerate(m Config) (*Mock, error) {
|
func RandomRows(m RowConfig) (*RowMock, error) {
|
||||||
//example struct cannot be nil and must be a struct
|
//example struct cannot be nil and must be a struct
|
||||||
if m.Example == nil {
|
if m.Example == nil {
|
||||||
return nil, errors.New("example value cannot be nil")
|
return nil, ErrBadExample
|
||||||
}
|
}
|
||||||
if reflect.ValueOf(m.Example).Kind() != reflect.Struct {
|
if reflect.ValueOf(m.Example).Kind() != reflect.Struct {
|
||||||
return nil, errors.New("example value must be a struct")
|
return nil, ErrBadExample
|
||||||
}
|
}
|
||||||
|
|
||||||
//any weirdness, just pull one row
|
//any weirdness, just pull one row
|
||||||
@@ -52,7 +70,7 @@ func RandomGenerate(m Config) (*Mock, error) {
|
|||||||
if len(m.Keys) > 0 {
|
if len(m.Keys) > 0 {
|
||||||
primaryKey = true
|
primaryKey = true
|
||||||
if len(m.Keys) != m.RowCount {
|
if len(m.Keys) != m.RowCount {
|
||||||
return nil, errors.New("you must provide a key for each row")
|
return nil, ErrMissingKeys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,14 +102,14 @@ func RandomGenerate(m Config) (*Mock, error) {
|
|||||||
//generate random values
|
//generate random values
|
||||||
nv := kindToRandom(field)
|
nv := kindToRandom(field)
|
||||||
if nv == nil {
|
if nv == nil {
|
||||||
return nil, fmt.Errorf("could not match type: %s", retType.Name())
|
return nil, ErrUnsupportedType
|
||||||
}
|
}
|
||||||
|
|
||||||
rows[y] = append(rows[y], nv)
|
rows[y] = append(rows[y], nv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Mock{
|
return &RowMock{
|
||||||
//sql is rebound and escaped for sqlmock.ExpectQuery
|
//sql is rebound and escaped for sqlmock.ExpectQuery
|
||||||
Query: sqlx.Rebind(sqlx.AT, regexp.QuoteMeta(m.Query)),
|
Query: sqlx.Rebind(sqlx.AT, regexp.QuoteMeta(m.Query)),
|
||||||
Columns: columns,
|
Columns: columns,
|
||||||
@@ -99,6 +117,52 @@ func RandomGenerate(m Config) (*Mock, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// so this would "work" but only accounts for inserting one row and doesn't allow for hardcoded ID's
|
||||||
|
// it would also have to account in the results struct these changes for rowsAffected, etc.
|
||||||
|
func RandomStruct(c StructConfig) (*StructMock, error) {
|
||||||
|
if c.Example == nil {
|
||||||
|
return nil, ErrBadExample
|
||||||
|
}
|
||||||
|
if reflect.ValueOf(c.Example).Kind() != reflect.Struct {
|
||||||
|
return nil, ErrBadExample
|
||||||
|
}
|
||||||
|
|
||||||
|
retType := reflect.TypeOf(c.Example)
|
||||||
|
maxFieldCount := retType.NumField()
|
||||||
|
filled := reflect.New(retType).Elem()
|
||||||
|
args := make([]any, 0, maxFieldCount)
|
||||||
|
|
||||||
|
for y := 0; y < maxFieldCount; y++ {
|
||||||
|
field := retType.Field(y)
|
||||||
|
dbTag := field.Tag.Get(DB_TAG)
|
||||||
|
if dbTag == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nv := kindToRandom(field)
|
||||||
|
if nv == nil {
|
||||||
|
return nil, ErrUnsupportedType
|
||||||
|
}
|
||||||
|
|
||||||
|
args[y] = nv
|
||||||
|
nf := filled.Field(y)
|
||||||
|
if nf.CanSet() {
|
||||||
|
filled.Field(y).Set(reflect.ValueOf(nv))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &StructMock{
|
||||||
|
Query: sqlx.Rebind(sqlx.AT, regexp.QuoteMeta(c.Query)),
|
||||||
|
Args: args,
|
||||||
|
MockStruct: filled,
|
||||||
|
Result: &sqlResult{
|
||||||
|
insertID: 1,
|
||||||
|
rowsAffected: 1,
|
||||||
|
err: nil,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// converts basic reflect Kind's to psuedo-random data, slices are given a random amount of entries
|
// converts basic reflect Kind's to psuedo-random data, slices are given a random amount of entries
|
||||||
func kindToRandom(field reflect.StructField) any {
|
func kindToRandom(field reflect.StructField) any {
|
||||||
kind := field.Type.Kind()
|
kind := field.Type.Kind()
|
||||||
|
Reference in New Issue
Block a user