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

package mocks

import (
	context "context"

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

	testing "testing"
)

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

// Add provides a mock function with given fields: ctx, s, user, message
func (_m *StrategyHistory) Add(ctx context.Context, s string, user string, message string) error {
	ret := _m.Called(ctx, s, user, message)

	var r0 error
	if rf, ok := ret.Get(0).(func(context.Context, string, string, string) error); ok {
		r0 = rf(ctx, s, user, message)
	} else {
		r0 = ret.Error(0)
	}

	return r0
}

// CurrentStrategy provides a mock function with given fields:
func (_m *StrategyHistory) CurrentStrategy() *strategy.StrategyChange {
	ret := _m.Called()

	var r0 *strategy.StrategyChange
	if rf, ok := ret.Get(0).(func() *strategy.StrategyChange); ok {
		r0 = rf()
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).(*strategy.StrategyChange)
		}
	}

	return r0
}

// GetHistory provides a mock function with given fields:
func (_m *StrategyHistory) GetHistory() []*strategy.StrategyChange {
	ret := _m.Called()

	var r0 []*strategy.StrategyChange
	if rf, ok := ret.Get(0).(func() []*strategy.StrategyChange); ok {
		r0 = rf()
	} else {
		if ret.Get(0) != nil {
			r0 = ret.Get(0).([]*strategy.StrategyChange)
		}
	}

	return r0
}

// Update provides a mock function with given fields: ctx
func (_m *StrategyHistory) Update(ctx context.Context) error {
	ret := _m.Called(ctx)

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

	return r0
}

// NewStrategyHistory creates a new instance of StrategyHistory. It also registers a cleanup function to assert the mocks expectations.
func NewStrategyHistory(t testing.TB) *StrategyHistory {
	mock := &StrategyHistory{}

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

	return mock
}
