// 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"

	testing "testing"
)

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

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

	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)

	var r0 *manual.ManualRollRequest
	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)
		}
	}

	var r1 error
	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)

	var r0 []*manual.ManualRollRequest
	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)
		}
	}

	var r1 error
	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)

	var r0 []*manual.ManualRollRequest
	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)
		}
	}

	var r1 error
	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)

	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 cleanup function to assert the mocks expectations.
func NewDB(t testing.TB) *DB {
	mock := &DB{}

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

	return mock
}
