Use mock dispatcher for testing event triggering.

This commit is contained in:
Alex Bramley 2011-11-07 14:50:23 +00:00
parent e04065dcbe
commit a271cc06f3
2 changed files with 15 additions and 58 deletions

View File

@ -5,7 +5,6 @@ import (
"github.com/fluffle/goirc/logging" "github.com/fluffle/goirc/logging"
"github.com/fluffle/goirc/state" "github.com/fluffle/goirc/state"
"gomock.googlecode.com/hg/gomock" "gomock.googlecode.com/hg/gomock"
"strings"
"testing" "testing"
"time" "time"
) )
@ -14,6 +13,7 @@ type testState struct {
ctrl *gomock.Controller ctrl *gomock.Controller
log *logging.MockLogger log *logging.MockLogger
st *state.MockStateTracker st *state.MockStateTracker
ed *event.MockEventDispatcher
nc *mockNetConn nc *mockNetConn
c *Conn c *Conn
} }
@ -22,6 +22,7 @@ func setUp(t *testing.T) (*Conn, *testState) {
ctrl := gomock.NewController(t) ctrl := gomock.NewController(t)
st := state.NewMockStateTracker(ctrl) st := state.NewMockStateTracker(ctrl)
r := event.NewRegistry() r := event.NewRegistry()
ed := event.NewMockEventDispatcher(ctrl)
l := logging.NewMockLogger(ctrl) l := logging.NewMockLogger(ctrl)
nc := MockNetConn(t) nc := MockNetConn(t)
c := Client("test", "test", "Testing IRC", r, l) c := Client("test", "test", "Testing IRC", r, l)
@ -30,6 +31,7 @@ func setUp(t *testing.T) (*Conn, *testState) {
// random crap that gets logged. This mocks it all out nicely. // random crap that gets logged. This mocks it all out nicely.
ctrl.RecordCall(l, "Debug", gomock.Any(), gomock.Any()).AnyTimes() ctrl.RecordCall(l, "Debug", gomock.Any(), gomock.Any()).AnyTimes()
c.ED = ed
c.ST = st c.ST = st
c.st = true c.st = true
c.sock = nc c.sock = nc
@ -45,12 +47,13 @@ func setUp(t *testing.T) (*Conn, *testState) {
t.Errorf("Conn.Me not correctly initialised.") t.Errorf("Conn.Me not correctly initialised.")
} }
return c, &testState{ctrl, l, st, nc, c} return c, &testState{ctrl, l, st, ed, nc, c}
} }
func (s *testState) tearDown() { func (s *testState) tearDown() {
// This can get set to false in some tests // This can get set to false in some tests
s.c.st = true s.c.st = true
s.ed.EXPECT().Dispatch("disconnected", s.c, &Line{})
s.st.EXPECT().Wipe() s.st.EXPECT().Wipe()
s.log.EXPECT().Error("irc.recv(): %s", "EOF") s.log.EXPECT().Error("irc.recv(): %s", "EOF")
s.log.EXPECT().Info("irc.shutdown(): Disconnected from server.") s.log.EXPECT().Info("irc.shutdown(): Disconnected from server.")
@ -60,30 +63,6 @@ func (s *testState) tearDown() {
s.ctrl.Finish() s.ctrl.Finish()
} }
func TestShutdown(t *testing.T) {
c, s := setUp(t)
// Setup a mock event dispatcher to test correct triggering of "disconnected"
flag := c.ExpectEvent("disconnected")
// Call shutdown via tearDown
s.tearDown()
// Verify that the connection no longer thinks it's connected
if c.Connected {
t.Errorf("Conn still thinks it's connected to the server.")
}
// Verify that the "disconnected" event fired correctly
if !*flag {
t.Errorf("Calling Close() didn't result in dispatch of disconnected event.")
}
// TODO(fluffle): Try to work out a way of testing that the background
// goroutines were *actually* stopped? Test m a bit more?
}
// Practically the same as the above test, but shutdown is called implicitly // Practically the same as the above test, but shutdown is called implicitly
// by recv() getting an EOF from the mock connection. // by recv() getting an EOF from the mock connection.
func TestEOF(t *testing.T) { func TestEOF(t *testing.T) {
@ -91,10 +70,8 @@ func TestEOF(t *testing.T) {
// Since we're not using tearDown() here, manually call Finish() // Since we're not using tearDown() here, manually call Finish()
defer s.ctrl.Finish() defer s.ctrl.Finish()
// Setup a mock event dispatcher to test correct triggering of "disconnected"
flag := c.ExpectEvent("disconnected")
// Simulate EOF from server // Simulate EOF from server
s.ed.EXPECT().Dispatch("disconnected", c, &Line{})
s.st.EXPECT().Wipe() s.st.EXPECT().Wipe()
s.log.EXPECT().Info("irc.shutdown(): Disconnected from server.") s.log.EXPECT().Info("irc.shutdown(): Disconnected from server.")
s.log.EXPECT().Error("irc.recv(): %s", "EOF") s.log.EXPECT().Error("irc.recv(): %s", "EOF")
@ -108,26 +85,8 @@ func TestEOF(t *testing.T) {
if c.Connected { if c.Connected {
t.Errorf("Conn still thinks it's connected to the server.") t.Errorf("Conn still thinks it's connected to the server.")
} }
// Verify that the "disconnected" event fired correctly
if !*flag {
t.Errorf("Calling Close() didn't result in dispatch of disconnected event.")
}
} }
// Mock dispatcher to verify that events are triggered successfully func TestEnableStateTracking(t *testing.T) {
type mockDispatcher func(string, ...interface{})
func (d mockDispatcher) Dispatch(name string, ev ...interface{}) {
d(name, ev...)
}
func (conn *Conn) ExpectEvent(name string) *bool {
flag := false
conn.ED = mockDispatcher(func(n string, ev ...interface{}) {
if n == strings.ToLower(name) {
flag = true
}
})
return &flag
} }

View File

@ -11,10 +11,14 @@ import (
// in this file will call their respective handlers synchronously, otherwise // in this file will call their respective handlers synchronously, otherwise
// testing becomes more difficult. // testing becomes more difficult.
func TestPING(t *testing.T) { func TestPING(t *testing.T) {
_, s := setUp(t) c, s := setUp(t)
defer s.tearDown() defer s.tearDown()
// As this is a real end-to-end test, we need a real end-to-end dispatcher.
c.ED = c.ER
s.nc.Send("PING :1234567890") s.nc.Send("PING :1234567890")
s.nc.Expect("PONG :1234567890") s.nc.Expect("PONG :1234567890")
// Return mock dispatcher to it's rightful place afterwards for tearDown.
c.ED = s.ed
} }
// Test the handler for 001 / RPL_WELCOME // Test the handler for 001 / RPL_WELCOME
@ -22,16 +26,10 @@ func Test001(t *testing.T) {
c, s := setUp(t) c, s := setUp(t)
defer s.tearDown() defer s.tearDown()
// Setup a mock event dispatcher to test correct triggering of "connected" l := parseLine(":irc.server.org 001 test :Welcome to IRC test!ident@somehost.com")
flag := c.ExpectEvent("connected") s.ed.EXPECT().Dispatch("connected", c, l)
// Call handler with a valid 001 line // Call handler with a valid 001 line
c.h_001(parseLine(":irc.server.org 001 test :Welcome to IRC test!ident@somehost.com")) c.h_001(l)
// Check that the event was dispatched correctly
if !*flag {
t.Errorf("Sending 001 didn't result in dispatch of connected event.")
}
// Check host parsed correctly // Check host parsed correctly
if c.Me.Host != "somehost.com" { if c.Me.Host != "somehost.com" {