func (h *Expecter) clone() *Expecter {
	return &Expecter{
		adapter:  h.adapter,
		callmap:  make(map[string][]interface{}),
		gorm:     h.gorm,
		noop:     h.noop,
		recorder: h.recorder,
	}
}
clone ensures that the original expecter does not have any unintended
conditions set by Where/Not etc. Recorder is _not_ cloned.
package gormexpect
import (
	"reflect"
	"github.com/davecgh/go-spew/spew"
	"github.com/jinzhu/gorm"
	sqlmock "gopkg.in/DATA-DOG/go-sqlmock.v1"
)
type AdapterFactory func(dialect string, args ...interface{}) (*gorm.DB, Adapter, error)
type Expecter struct {
	adapter  Adapter
	callmap  map[string][]interface{}  
	gorm     *gorm.DB
	noop     NoopController
	recorder *Recorder
}
func NewDefaultExpecter() (*gorm.DB, *Expecter, error) {
	gormMock, adapter, err := NewSqlmockAdapter("sqlmock", "mock_gorm_dsn")
	if err != nil {
		return nil, nil, err
	}
	recorder := &Recorder{}
	noop, noopc, _ := NewNoopDB()
	gormNoop, _ := gorm.Open("sqlmock", noop)
	gormNoop = gormNoop.Set("gorm:recorder", recorder)
	gormNoop.Callback().Create().After("gorm:create").Register("gorm_expect:record_exec", recordExecCallback)
	gormNoop.Callback().Query().After("gorm:query").Register("gorm_expect:record_query", recordQueryCallback)
	gormNoop.Callback().Query().Before("gorm:preload").Register("gorm_expect:record_preload", recordPreloadCallback)
	gormNoop.Callback().RowQuery().After("gorm:row_query").Register("gorm_expect:record_row_query", recordQueryCallback)
	gormNoop.Callback().Update().After("gorm:update").Register("gorm_expect:record_update", recordExecCallback)
	gormNoop.Callback().Delete().After("gorm:delete").Register("gorm_expect:record_delete", recordExecCallback)
	return gormMock, &Expecter{
		adapter:  adapter,
		callmap:  make(map[string][]interface{}),
		gorm:     gormNoop,
		noop:     noopc,
		recorder: recorder,
	}, nil
}
func NewExpecter(fn AdapterFactory, dialect string, args ...interface{}) (*gorm.DB, *Expecter, error) {
	gormDb, adapter, err := fn(dialect, args...)
	if err != nil {
		return nil, nil, err
	}
	return gormDb, &Expecter{adapter: adapter}, nil
}
func (h *Expecter) Debug() *Expecter {
	h.gorm = h.gorm.Debug()
	return h
}
func (h *Expecter) Skip(hook string, callbackName string) *Expecter {
	clone := h.clone()
	switch hook {
	case "Create":
		clone.gorm.Callback().Create().Remove(callbackName)
	case "Query":
		clone.gorm.Callback().Query().Remove(callbackName)
	case "Update":
		clone.gorm.Callback().Update().Remove(callbackName)
	case "Delete":
		clone.gorm.Callback().Delete().Remove(callbackName)
	default:
		panic("hook can only be Create, QUery, Update or Delete")
	}
	return clone
}
func (h *Expecter) AssertExpectations() error {
	return h.adapter.AssertExpectations()
}
func (h *Expecter) Association(column string) *MockAssociation {
	gormAssociation := h.gorm.Association(column)
	return NewMockAssociation(column, gormAssociation, h)
}
func (h *Expecter) Model(model interface{}) *Expecter {
	h.gorm = h.gorm.Model(model)
	return h
}
func (h *Expecter) Begin() TxBeginner {
	return h.adapter.ExpectBegin()
}
func (h *Expecter) Commit() TxCommitter {
	return h.adapter.ExpectCommit()
}
func (h *Expecter) Rollback() TxRollback {
	return h.adapter.ExpectRollback()
}
func (h *Expecter) Create(model interface{}) ExecExpectation {
	h.gorm = h.gorm.Create(model)
	return h.exec()
}
func (h *Expecter) Limit(limit int) *Expecter {
	clone := h.clone()
	clone.gorm = clone.gorm.Limit(limit)
	return clone
}
func (h *Expecter) Offset(offset int) *Expecter {
	clone := h.clone()
	clone.gorm = clone.gorm.Offset(offset)
	return clone
}
func (h *Expecter) Assign(attrs ...interface{}) *Expecter {
	clone := h.clone()
	clone.gorm = clone.gorm.Assign(attrs...)
	return clone
}
func (h *Expecter) Where(query interface{}, args ...interface{}) *Expecter {
	clone := h.clone()
	clone.gorm = clone.gorm.Where(query, args...)
	return clone
}
func (h *Expecter) Not(query interface{}, args ...interface{}) *Expecter {
	clone := h.clone()
	clone.gorm = clone.gorm.Not(query, args...)
	return clone
}
func (h *Expecter) Preload(column string, conditions ...interface{}) *Expecter {
	h.gorm = h.gorm.Preload(column, conditions...)
	return h
}
func (h *Expecter) First(out interface{}, where ...interface{}) QueryExpectation {
	var args []interface{}
	args = append(args, out)
	args = append(args, where...)
	h.callmap["First"] = args
	return h.query()
}
func (h *Expecter) FirstOrCreate(out interface{}, returns interface{}, where ...interface{}) ExecExpectation {
	if returns == nil {
		h.noop.ReturnNilRows()
		h.gorm.FirstOrCreate(out)
		query, _ := h.recorder.GetFirst()
		h.adapter.ExpectQuery(query).Returns(sqlmock.NewRows([]string{}))
		return h.exec()
	}
	outType := indirect(reflect.ValueOf(out)).Type()
	returnsType := indirect(reflect.ValueOf(returns)).Type()
	if outType != returnsType {
		panic(spew.Sprintf("out and returns should be of the same type. Got %s and %s.\r\n", outType.String(), returnsType.String()))
	}
	h.gorm.FirstOrCreate(out)
	query, _ := h.recorder.GetFirst()
	clone := h.new()
	clone.recorder.stmts = []Stmt{query}
	queryExpectation := SqlmockQueryExpectation{parent: clone, scope: (&gorm.Scope{}).New(returns)}
	h.adapter.ExpectQuery(query).Returns(queryExpectation.getDestRows(returns))
	if !h.recorder.IsEmpty() {
		return h.exec()
	}
	return nil
}
func (h *Expecter) FirstOrInit(out interface{}, returns interface{}, where ...interface{}) *Expecter {
	var args []interface{}
	args = append(args, out)
	args = append(args, where...)
	h.callmap["FirstOrInit"] = args
	h.query().Returns(returns)
	h.reset()
	return h
}
func (h *Expecter) Find(out interface{}, where ...interface{}) QueryExpectation {
	var args []interface{}
	args = append(args, out)
	args = append(args, where...)
	h.callmap["Find"] = args
	return h.query()
}
func (h *Expecter) Count(out interface{}) QueryExpectation {
	var args []interface{}
	args = append(args, out)
	h.callmap["Count"] = args
	return h.query()
}
func (h *Expecter) Save(model interface{}) ExecExpectation {
	h.gorm.Save(model)
	return h.exec()
}
func (h *Expecter) Update(attrs ...interface{}) ExecExpectation {
	h.gorm.Update(attrs...)
	return h.exec()
}
func (h *Expecter) Updates(values interface{}, ignoreProtectedAttrs ...bool) ExecExpectation {
	h.gorm.Updates(values, ignoreProtectedAttrs...)
	return h.exec()
}
func (h *Expecter) Delete(model interface{}, where ...interface{}) ExecExpectation {
	h.gorm.Delete(model, where...)
	return h.exec()
}