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

package mocks

import (
	context "context"
	io "io"

	mock "github.com/stretchr/testify/mock"

	pgx "github.com/jackc/pgx/v4"

	shortcut "go.skia.org/infra/perf/go/shortcut"
)

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

// DeleteShortcut provides a mock function with given fields: ctx, id, tx
func (_m *Store) DeleteShortcut(ctx context.Context, id string, tx pgx.Tx) error {
	ret := _m.Called(ctx, id, tx)

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

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, pgx.Tx) error); ok {
		r0 = rf(ctx, id, tx)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// Get provides a mock function with given fields: ctx, id
func (_m *Store) Get(ctx context.Context, id string) (*shortcut.Shortcut, error) {
	ret := _m.Called(ctx, id)

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

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

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

	return r0, r1
}

// GetAll provides a mock function with given fields: ctx
func (_m *Store) GetAll(ctx context.Context) (<-chan *shortcut.Shortcut, error) {
	ret := _m.Called(ctx)

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

	var r0 <-chan *shortcut.Shortcut
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context) (<-chan *shortcut.Shortcut, error)); ok {
		return rf(ctx)
	}
	if rf, ok := ret.Get(0).(func(context.Context) <-chan *shortcut.Shortcut); ok {
		r0 = rf(ctx)
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(<-chan *shortcut.Shortcut)
		}
	}

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

	return r0, r1
}

// Insert provides a mock function with given fields: ctx, r
func (_m *Store) Insert(ctx context.Context, r io.Reader) (string, error) {
	ret := _m.Called(ctx, r)

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

	var r0 string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, io.Reader) (string, error)); ok {
		return rf(ctx, r)
	}
	if rf, ok := ret.Get(0).(func(context.Context, io.Reader) string); ok {
		r0 = rf(ctx, r)
	} else {
		r0 = ret.Get(0).(string)
	}

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

	return r0, r1
}

// InsertShortcut provides a mock function with given fields: ctx, _a1
func (_m *Store) InsertShortcut(ctx context.Context, _a1 *shortcut.Shortcut) (string, error) {
	ret := _m.Called(ctx, _a1)

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

	var r0 string
	var r1 error
	if rf, ok := ret.Get(0).(func(context.Context, *shortcut.Shortcut) (string, error)); ok {
		return rf(ctx, _a1)
	}
	if rf, ok := ret.Get(0).(func(context.Context, *shortcut.Shortcut) string); ok {
		r0 = rf(ctx, _a1)
	} else {
		r0 = ret.Get(0).(string)
	}

	if rf, ok := ret.Get(1).(func(context.Context, *shortcut.Shortcut) error); ok {
		r1 = rf(ctx, _a1)
	} else {
		r1 = ret.Error(1)
	}

	return r0, r1
}

// NewStore creates a new instance of Store. 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 NewStore(t interface {
	mock.TestingT
	Cleanup(func())
}) *Store {
	mock := &Store{}
	mock.Mock.Test(t)

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

	return mock
}
