2011-08-21 12:38:51 +00:00
|
|
|
package client
|
|
|
|
|
2011-08-23 09:49:22 +00:00
|
|
|
import (
|
2011-09-29 21:54:54 +00:00
|
|
|
"github.com/fluffle/goirc/logging"
|
2011-11-06 04:56:46 +00:00
|
|
|
"github.com/fluffle/goirc/state"
|
|
|
|
"gomock.googlecode.com/hg/gomock"
|
2011-08-23 09:49:22 +00:00
|
|
|
"strings"
|
|
|
|
"testing"
|
2011-08-23 09:53:52 +00:00
|
|
|
"time"
|
2011-08-23 09:49:22 +00:00
|
|
|
)
|
2011-08-21 12:38:51 +00:00
|
|
|
|
2011-11-06 04:56:46 +00:00
|
|
|
type testState struct {
|
|
|
|
ctrl *gomock.Controller
|
|
|
|
log *logging.MockLogger
|
|
|
|
st *state.MockStateTracker
|
|
|
|
nc *mockNetConn
|
|
|
|
c *Conn
|
2011-09-29 21:54:54 +00:00
|
|
|
}
|
|
|
|
|
2011-11-06 04:56:46 +00:00
|
|
|
func setUp(t *testing.T) (*Conn, *testState) {
|
|
|
|
ctrl := gomock.NewController(t)
|
|
|
|
st := state.NewMockStateTracker(ctrl)
|
|
|
|
l := logging.NewMockLogger(ctrl)
|
|
|
|
nc := MockNetConn(t)
|
|
|
|
c := New("test", "test", "Testing IRC", false, nil, l)
|
|
|
|
|
|
|
|
// We don't want to have to specify s.log.EXPECT().Debug() for all the
|
|
|
|
// random crap that gets logged. This mocks it all out nicely.
|
|
|
|
ctrl.RecordCall(l, "Debug", gomock.Any(), gomock.Any()).AnyTimes()
|
|
|
|
|
|
|
|
c.ST = st
|
|
|
|
c.st = true
|
|
|
|
c.sock = nc
|
|
|
|
c.Flood = true // Tests can take a while otherwise
|
|
|
|
c.Connected = true
|
|
|
|
c.postConnect()
|
2011-08-24 12:53:28 +00:00
|
|
|
|
2011-08-24 12:55:18 +00:00
|
|
|
// Assert some basic things about the initial state of the Conn struct
|
|
|
|
if c.Me.Nick != "test" ||
|
|
|
|
c.Me.Ident != "test" ||
|
|
|
|
c.Me.Name != "Testing IRC" ||
|
|
|
|
c.Me.Host != "" {
|
|
|
|
t.Errorf("Conn.Me not correctly initialised.")
|
|
|
|
}
|
|
|
|
|
2011-11-06 04:56:46 +00:00
|
|
|
return c, &testState{ctrl, l, st, nc, c}
|
2011-08-21 12:38:51 +00:00
|
|
|
}
|
2011-08-22 22:23:29 +00:00
|
|
|
|
2011-11-06 04:56:46 +00:00
|
|
|
func (s *testState) tearDown() {
|
|
|
|
// This can get set to false in some tests
|
|
|
|
s.c.st = true
|
|
|
|
s.st.EXPECT().Wipe()
|
|
|
|
s.log.EXPECT().Error("irc.recv(): %s", "EOF")
|
|
|
|
s.log.EXPECT().Info("irc.shutdown(): Disconnected from server.")
|
|
|
|
s.nc.ExpectNothing()
|
|
|
|
s.c.shutdown()
|
|
|
|
<-time.After(1e6)
|
|
|
|
s.ctrl.Finish()
|
2011-08-24 12:53:28 +00:00
|
|
|
}
|
|
|
|
|
2011-11-06 04:56:46 +00:00
|
|
|
|
2011-08-23 09:53:52 +00:00
|
|
|
func TestShutdown(t *testing.T) {
|
2011-11-06 04:56:46 +00:00
|
|
|
c, s := setUp(t)
|
2011-08-23 09:53:52 +00:00
|
|
|
|
|
|
|
// Setup a mock event dispatcher to test correct triggering of "disconnected"
|
2011-11-06 04:56:46 +00:00
|
|
|
flag := c.ExpectEvent("disconnected")
|
2011-08-23 09:53:52 +00:00
|
|
|
|
2011-11-06 04:56:46 +00:00
|
|
|
// Call shutdown via tearDown
|
|
|
|
s.tearDown()
|
2011-08-23 09:53:52 +00:00
|
|
|
|
|
|
|
// 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
|
2011-11-06 04:56:46 +00:00
|
|
|
if !*flag {
|
2011-08-23 09:53:52 +00:00
|
|
|
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
|
|
|
|
// by recv() getting an EOF from the mock connection.
|
|
|
|
func TestEOF(t *testing.T) {
|
2011-11-06 04:56:46 +00:00
|
|
|
c, s := setUp(t)
|
|
|
|
// Since we're not using tearDown() here, manually call Finish()
|
|
|
|
defer s.ctrl.Finish()
|
2011-08-23 09:53:52 +00:00
|
|
|
|
|
|
|
// Setup a mock event dispatcher to test correct triggering of "disconnected"
|
2011-11-06 04:56:46 +00:00
|
|
|
flag := c.ExpectEvent("disconnected")
|
2011-08-23 09:53:52 +00:00
|
|
|
|
|
|
|
// Simulate EOF from server
|
2011-11-06 04:56:46 +00:00
|
|
|
s.st.EXPECT().Wipe()
|
|
|
|
s.log.EXPECT().Info("irc.shutdown(): Disconnected from server.")
|
|
|
|
s.log.EXPECT().Error("irc.recv(): %s", "EOF")
|
|
|
|
s.nc.Close()
|
2011-08-23 09:53:52 +00:00
|
|
|
|
2011-09-29 21:54:54 +00:00
|
|
|
// Since things happen in different internal goroutines, we need to wait
|
|
|
|
// 1 ms should be enough :-)
|
2011-11-06 04:56:46 +00:00
|
|
|
<-time.After(1e6)
|
2011-08-23 09:53:52 +00:00
|
|
|
|
|
|
|
// 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
|
2011-11-06 04:56:46 +00:00
|
|
|
if !*flag {
|
2011-08-23 09:53:52 +00:00
|
|
|
t.Errorf("Calling Close() didn't result in dispatch of disconnected event.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-22 22:23:29 +00:00
|
|
|
// Mock dispatcher to verify that events are triggered successfully
|
|
|
|
type mockDispatcher func(string, ...interface{})
|
|
|
|
|
|
|
|
func (d mockDispatcher) Dispatch(name string, ev ...interface{}) {
|
|
|
|
d(name, ev...)
|
|
|
|
}
|
2011-08-23 09:49:22 +00:00
|
|
|
|
2011-11-06 04:56:46 +00:00
|
|
|
func (conn *Conn) ExpectEvent(name string) *bool {
|
|
|
|
flag := false
|
|
|
|
conn.ED = mockDispatcher(func(n string, ev ...interface{}) {
|
2011-08-23 09:49:22 +00:00
|
|
|
if n == strings.ToLower(name) {
|
2011-11-06 04:56:46 +00:00
|
|
|
flag = true
|
2011-08-23 09:49:22 +00:00
|
|
|
}
|
|
|
|
})
|
2011-11-06 04:56:46 +00:00
|
|
|
return &flag
|
2011-08-23 09:49:22 +00:00
|
|
|
}
|