Finish bind tests

- One test failing because lack of idMap usage
This commit is contained in:
Aaron L 2016-08-07 18:06:09 -07:00
parent ee2b4e7990
commit 113754d38b
2 changed files with 224 additions and 33 deletions

View file

@ -98,7 +98,7 @@ func bind(q *Query, obj interface{}, structType, sliceType reflect.Type, singula
var ptrSlice reflect.Value
if !singular {
ptrSlice = reflect.ValueOf(obj)
ptrSlice = reflect.Indirect(reflect.ValueOf(obj))
}
for rows.Next() {
@ -146,9 +146,6 @@ func bindPtrs(obj interface{}, cols ...string) ([]interface{}, error) {
}
func findField(names []string, v reflect.Value) (interface{}, bool) {
fmt.Println("Names:", names)
fmt.Println("Type:", v.Type().String())
if !v.IsValid() || len(names) == 0 {
return nil, false
}
@ -167,46 +164,33 @@ func findField(names []string, v reflect.Value) (interface{}, bool) {
name := strmangle.TitleCase(names[0])
typ := v.Type()
fi, ok := typ.FieldByName(name)
if ok {
fieldName, recurse := getBoilTag(fi)
if fieldName != "-" {
if recurse {
return findField(names[1:], v.FieldByName(name))
}
if len(names) == 1 {
field := v.FieldByName(name)
if field.Kind() != reflect.Ptr {
return field.Addr().Interface(), true
}
return field.Interface(), true
}
}
}
n := typ.NumField()
for i := 0; i < n; i++ {
f := typ.Field(i)
fieldName, recurse := getBoilTag(f)
fmt.Println(name, fieldName, recurse)
if fieldName == "-" {
continue
}
if recurse {
return findField(names, v.Field(i))
if fieldName == name {
names = names[1:]
}
if ptr, ok := findField(names, v.Field(i)); ok {
return ptr, ok
}
}
if fieldName == name {
fieldVal := v.Field(i)
if fieldVal.Kind() != reflect.Ptr {
return fieldVal.Addr().Interface(), true
}
return fieldVal.Interface(), true
if fieldName != name || len(names) > 1 {
continue
}
fieldVal := v.Field(i)
if fieldVal.Kind() != reflect.Ptr {
return fieldVal.Addr().Interface(), true
}
return fieldVal.Interface(), true
}
return nil, false
@ -219,7 +203,9 @@ func getBoilTag(field reflect.StructField) (name string, recurse bool) {
tagTokens := strings.Split(tag, ",")
name = strmangle.TitleCase(tagTokens[0])
recurse = len(tagTokens) > 1 && tagTokens[1] == "bind"
} else {
}
if len(name) == 0 {
name = field.Name
}

View file

@ -1,14 +1,217 @@
package boil
import (
"database/sql/driver"
"testing"
"time"
"gopkg.in/DATA-DOG/go-sqlmock.v1"
"gopkg.in/nullbio/null.v4"
)
type mockRowMaker struct {
int
rows []driver.Value
}
func TestBind(t *testing.T) {
t.Skip("Not implemented")
t.Parallel()
testResults := []*struct {
ID int
Name string `boil:"test"`
}{}
query := &Query{
from: []string{"fun"},
}
db, mock, err := sqlmock.New()
if err != nil {
t.Error(err)
}
ret := sqlmock.NewRows([]string{"id", "test"})
ret.AddRow(driver.Value(int64(35)), driver.Value("pat"))
ret.AddRow(driver.Value(int64(12)), driver.Value("cat"))
mock.ExpectQuery(`SELECT \* FROM "fun";`).WillReturnRows(ret)
SetExecutor(query, db)
err = query.Bind(&testResults)
if err != nil {
t.Error(err)
}
if len(testResults) != 2 {
t.Fatal("wrong number of results:", len(testResults))
}
if id := testResults[0].ID; id != 35 {
t.Error("wrong ID:", id)
}
if name := testResults[0].Name; name != "pat" {
t.Error("wrong name:", name)
}
if id := testResults[1].ID; id != 12 {
t.Error("wrong ID:", id)
}
if name := testResults[1].Name; name != "cat" {
t.Error("wrong name:", name)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Error(err)
}
}
func TestBindSingular(t *testing.T) {
t.Parallel()
testResults := struct {
ID int
Name string `boil:"test"`
}{}
query := &Query{
from: []string{"fun"},
}
db, mock, err := sqlmock.New()
if err != nil {
t.Error(err)
}
ret := sqlmock.NewRows([]string{"id", "test"})
ret.AddRow(driver.Value(int64(35)), driver.Value("pat"))
mock.ExpectQuery(`SELECT \* FROM "fun";`).WillReturnRows(ret)
SetExecutor(query, db)
err = query.Bind(&testResults)
if err != nil {
t.Error(err)
}
if id := testResults.ID; id != 35 {
t.Error("wrong ID:", id)
}
if name := testResults.Name; name != "pat" {
t.Error("wrong name:", name)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Error(err)
}
}
func TestBind_InnerJoin(t *testing.T) {
t.Parallel()
testResults := []*struct {
Happy struct {
ID int `boil:"identifier"`
} `boil:",bind"`
Fun struct {
ID int `boil:"id"`
} `boil:",bind"`
}{}
query := &Query{
from: []string{"fun"},
joins: []join{{kind: JoinInner, clause: "happy as h on fun.id = h.fun_id"}},
}
db, mock, err := sqlmock.New()
if err != nil {
t.Error(err)
}
ret := sqlmock.NewRows([]string{"id"})
ret.AddRow(driver.Value(int64(10)))
ret.AddRow(driver.Value(int64(11)))
mock.ExpectQuery(`SELECT "fun"\.\* FROM "fun" INNER JOIN happy as h on fun.id = h.fun_id;`).WillReturnRows(ret)
SetExecutor(query, db)
err = query.Bind(&testResults)
if err != nil {
t.Error(err)
}
if len(testResults) != 2 {
t.Fatal("wrong number of results:", len(testResults))
}
if id := testResults[0].Happy.ID; id != 0 {
t.Error("wrong ID:", id)
}
if id := testResults[0].Fun.ID; id != 10 {
t.Error("wrong ID:", id)
}
if id := testResults[1].Happy.ID; id != 0 {
t.Error("wrong ID:", id)
}
if id := testResults[1].Fun.ID; id != 11 {
t.Error("wrong ID:", id)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Error(err)
}
}
func TestBind_InnerJoinSelect(t *testing.T) {
t.Parallel()
testResults := []*struct {
Happy struct {
ID int
} `boil:",bind"`
Fun struct {
ID int
} `boil:",bind"`
}{}
query := &Query{
selectCols: []string{"fun.id", "h.id"},
from: []string{"fun"},
joins: []join{{kind: JoinInner, clause: "happy as h on fun.happy_id = h.id"}},
}
db, mock, err := sqlmock.New()
if err != nil {
t.Error(err)
}
ret := sqlmock.NewRows([]string{"fun.id", "h.id"})
ret.AddRow(driver.Value(int64(10)), driver.Value(int64(11)))
ret.AddRow(driver.Value(int64(12)), driver.Value(int64(13)))
mock.ExpectQuery(`SELECT "fun"."id" as "fun.id","h"."id" as "h.id" FROM "fun" INNER JOIN happy as h on fun.happy_id = h.id;`).WillReturnRows(ret)
SetExecutor(query, db)
err = query.Bind(&testResults)
if err != nil {
t.Error(err)
}
if len(testResults) != 2 {
t.Fatal("wrong number of results:", len(testResults))
}
if id := testResults[0].Happy.ID; id != 11 {
t.Error("wrong ID:", id)
}
if id := testResults[0].Fun.ID; id != 10 {
t.Error("wrong ID:", id)
}
if id := testResults[1].Happy.ID; id != 13 {
t.Error("wrong ID:", id)
}
if id := testResults[1].Fun.ID; id != 12 {
t.Error("wrong ID:", id)
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Error(err)
}
}
func TestBindPtrs_Easy(t *testing.T) {
@ -60,6 +263,8 @@ func TestBindPtrs_Recursive(t *testing.T) {
}
func TestBindPtrs_RecursiveTags(t *testing.T) {
t.Parallel()
testStruct := struct {
Happy struct {
ID int `boil:"identifier"`