package tgmock import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.mau.fi/mautrix-telegram/pkg/gotd/bin" ) // TestingT is simplified *testing.T interface. type TestingT interface { require.TestingT assert.TestingT Helper() Cleanup(cb func()) } // Mock is a mock for tg.Invoker with testify/require support. type Mock struct { calls []Handler assert assertions } // Option configures Mock. type Option interface { apply(t TestingT, m *Mock) } type assertions interface { Truef(value bool, msg string, args ...interface{}) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) } type assertAssertions struct { assert *assert.Assertions } func (a assertAssertions) Equal(expected, actual interface{}, msgAndArgs ...interface{}) { a.assert.Equal(expected, actual, msgAndArgs...) } func (a assertAssertions) Truef(value bool, msg string, args ...interface{}) { a.assert.Truef(value, msg, args...) } type optionFunc func(t TestingT, m *Mock) func (o optionFunc) apply(t TestingT, m *Mock) { o(t, m) } // WithRequire configures mock to use "require" assertions. func WithRequire() Option { return optionFunc(func(t TestingT, m *Mock) { m.assert = require.New(t) }) } // NewRequire creates new Mock with "require" assertions. func NewRequire(t TestingT) *Mock { return New(t, WithRequire()) } // New creates new Mock. func New(t TestingT, options ...Option) *Mock { m := &Mock{ assert: &assertAssertions{ assert: assert.New(t), }, } for _, o := range options { o.apply(t, m) } t.Cleanup(func() { m.assert.Truef( m.AllWereMet(), "not all expected calls happen (expected yet %d)", len(m.calls), ) }) return m } // AllWereMet returns true if all expected calls happened. func (i *Mock) AllWereMet() bool { return len(i.calls) == 0 } func (i *Mock) add(h Handler) *Mock { i.calls = append(i.calls, h) return i } func (i *Mock) pop() (Handler, bool) { if len(i.calls) < 1 { return nil, false } h := i.calls[0] // Delete from SliceTricks. copy(i.calls, i.calls[1:]) i.calls[len(i.calls)-1] = nil i.calls = i.calls[:len(i.calls)-1] return h, true } // Handler returns HandlerFunc of Mock. func (i *Mock) Handler() HandlerFunc { return func(id int64, body bin.Encoder) (bin.Encoder, error) { h, ok := i.pop() i.assert.Truef(ok, "unexpected call") return h.Handle(id, body) } }