Skip to content

Commit

Permalink
Update handlers to receive an interface for the Session
Browse files Browse the repository at this point in the history
Please be aware, this is a breaking API change.

This change adds a new `discordgo` type, `Sessioner`, which is an interface that
describes the full method set for the `*Session` type. In addition to the new
type, this change updates the package to no longer send a concrete `*Session`
value in to handlers it invokes as the first argument but a `Sessioner` instead.
This is to make testing of handlers much easier, as mock implementations of the
Sessioner interface can be passed right in.

This also renames the internal state field from `State` to `state`, and adds a
new method to `*Session`, `State()`, to expose that internal state to consumers.
A test was added to ensure this method works as expected.

The example projects were updated where necessary to work with the new API

Fixes bwmarrin#662.

Signed-off-by: Tim Heckman <t@heckman.io>
  • Loading branch information
theckman committed Jun 21, 2019
1 parent 347a4f6 commit e98a50d
Show file tree
Hide file tree
Showing 14 changed files with 1,023 additions and 170 deletions.
2 changes: 1 addition & 1 deletion discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func New(args ...interface{}) (s *Session, err error) {

// Create an empty Session interface.
s = &Session{
State: NewState(),
state: NewState(),
Ratelimiter: NewRatelimiter(),
StateEnabled: true,
Compress: true,
Expand Down
8 changes: 4 additions & 4 deletions discord_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,17 @@ func TestOpenClose(t *testing.T) {
func TestAddHandler(t *testing.T) {

testHandlerCalled := int32(0)
testHandler := func(s *Session, m *MessageCreate) {
testHandler := func(s Sessioner, m *MessageCreate) {
atomic.AddInt32(&testHandlerCalled, 1)
}

interfaceHandlerCalled := int32(0)
interfaceHandler := func(s *Session, i interface{}) {
interfaceHandler := func(s Sessioner, i interface{}) {
atomic.AddInt32(&interfaceHandlerCalled, 1)
}

bogusHandlerCalled := int32(0)
bogusHandler := func(s *Session, se *Session) {
bogusHandler := func(s Sessioner, se *Session) {
atomic.AddInt32(&bogusHandlerCalled, 1)
}

Expand Down Expand Up @@ -181,7 +181,7 @@ func TestAddHandler(t *testing.T) {
func TestRemoveHandler(t *testing.T) {

testHandlerCalled := int32(0)
testHandler := func(s *Session, m *MessageCreate) {
testHandler := func(s Sessioner, m *MessageCreate) {
atomic.AddInt32(&testHandlerCalled, 1)
}

Expand Down
8 changes: 4 additions & 4 deletions event.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type EventHandler interface {
// Handle is called whenever an event of Type() happens.
// It is the receivers responsibility to type assert that the interface
// is the expected struct.
Handle(*Session, interface{})
Handle(Sessioner, interface{})
}

// EventInterfaceProvider is an interface for providing empty interfaces for
Expand All @@ -27,15 +27,15 @@ type EventInterfaceProvider interface {
const interfaceEventType = "__INTERFACE__"

// interfaceEventHandler is an event handler for interface{} events.
type interfaceEventHandler func(*Session, interface{})
type interfaceEventHandler func(Sessioner, interface{})

// Type returns the event type for interface{} events.
func (eh interfaceEventHandler) Type() string {
return interfaceEventType
}

// Handle is the handler for an interface{} event.
func (eh interfaceEventHandler) Handle(s *Session, i interface{}) {
func (eh interfaceEventHandler) Handle(s Sessioner, i interface{}) {
eh(s, i)
}

Expand Down Expand Up @@ -233,7 +233,7 @@ func (s *Session) onInterface(i interface{}) {
case *VoiceStateUpdate:
go s.onVoiceStateUpdate(t)
}
err := s.State.OnInterface(s, i)
err := s.state.OnInterface(s, i)
if err != nil {
s.log(LogDebug, "error dispatching internal event, %s", err)
}
Expand Down
Loading

0 comments on commit e98a50d

Please sign in to comment.