// Code generated by mockery v0.0.0-dev. DO NOT EDIT.

package mocks

import (
	context "context"

	mock "github.com/stretchr/testify/mock"
	manual "go.skia.org/infra/autoroll/go/manual"
)

// DB is an autogenerated mock type for the DB type
type DB struct {
	mock.Mock
}

// Close provides a mock function with no fields
func (_m *DB) Close() error {
	ret := _m.Called()

	if len(ret) == 0 {
		panic("no return value specified for Close")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func() error); ok {
		r0 = rf()
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// Get provides a mock function with given fields: ctx, rollId
func (_m *DB) Get(ctx context.Context, rollId string) (*manual.ManualRollRequest, error) {
	ret := _m.Called(ctx, rollId)

	if len(ret) == 0 {
		panic("no return value specified for Get")
	}

	var r0 *manual.ManualRollRequest
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, string) (*manual.ManualRollRequest, error)); ok {
		return rf(ctx, rollId)
	}
	if rf, ok := ret.Get(0).(func(context.Context, string) *manual.ManualRollRequest); ok {
		r0 = rf(ctx, rollId)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*manual.ManualRollRequest)
		}
	}

	if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
		r1 = rf(ctx, rollId)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// GetIncomplete provides a mock function with given fields: rollerName
func (_m *DB) GetIncomplete(rollerName string) ([]*manual.ManualRollRequest, error) {
	ret := _m.Called(rollerName)

	if len(ret) == 0 {
		panic("no return value specified for GetIncomplete")
	}

	var r0 []*manual.ManualRollRequest
	var r1 error
	if rf, ok := ret.Get(0).(func(string) ([]*manual.ManualRollRequest, error)); ok {
		return rf(rollerName)
	}
	if rf, ok := ret.Get(0).(func(string) []*manual.ManualRollRequest); ok {
		r0 = rf(rollerName)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*manual.ManualRollRequest)
		}
	}

	if rf, ok := ret.Get(1).(func(string) error); ok {
		r1 = rf(rollerName)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// GetRecent provides a mock function with given fields: rollerName, limit
func (_m *DB) GetRecent(rollerName string, limit int) ([]*manual.ManualRollRequest, error) {
	ret := _m.Called(rollerName, limit)

	if len(ret) == 0 {
		panic("no return value specified for GetRecent")
	}

	var r0 []*manual.ManualRollRequest
	var r1 error
	if rf, ok := ret.Get(0).(func(string, int) ([]*manual.ManualRollRequest, error)); ok {
		return rf(rollerName, limit)
	}
	if rf, ok := ret.Get(0).(func(string, int) []*manual.ManualRollRequest); ok {
		r0 = rf(rollerName, limit)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*manual.ManualRollRequest)
		}
	}

	if rf, ok := ret.Get(1).(func(string, int) error); ok {
		r1 = rf(rollerName, limit)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// Put provides a mock function with given fields: req
func (_m *DB) Put(req *manual.ManualRollRequest) error {
	ret := _m.Called(req)

	if len(ret) == 0 {
		panic("no return value specified for Put")
	}

	var r0 error
	if rf, ok := ret.Get(0).(func(*manual.ManualRollRequest) error); ok {
		r0 = rf(req)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// NewDB creates a new instance of DB. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewDB(t interface {
	mock.TestingT
	Cleanup(func())
}) *DB {
	mock := &DB{}
	mock.Mock.Test(t)

	t.Cleanup(func() { mock.AssertExpectations(t) })

	return mock
}
