         expect(@robot.emit).to.have.been.called
         expect(goodListenerCalled).to.be.ok
 
+  describe 'Listener Registration', ->
+    describe '#hear', ->
+      it 'matches TextMessages', ->
+        callback = sinon.spy()
+        testMessage = new TextMessage(@user, 'message123')
+        testRegex = /^message123$/
+
+        @robot.hear(testRegex, callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.be.ok
+
+      it 'does not match EnterMessages', ->
+        callback = sinon.spy()
+        testMessage = new EnterMessage(@user)
+        testRegex = /.*/
+
+        @robot.hear(testRegex, callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.not.be.ok
+
+    describe '#respond', ->
+      it 'matches TextMessages addressed to the robot', ->
+        callback = sinon.spy()
+        testMessage = new TextMessage(@user, 'TestHubot message123')
+        testRegex = /message123$/
+
+        @robot.respond(testRegex, callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.be.ok
+
+      it 'does not match EnterMessages', ->
+        callback = sinon.spy()
+        testMessage = new EnterMessage(@user)
+        testRegex = /.*/
+
+        @robot.respond(testRegex, callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.not.be.ok
+
+    describe '#enter', ->
+      it 'matches EnterMessages', ->
+        callback = sinon.spy()
+        testMessage = new EnterMessage(@user)
+
+        @robot.enter(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.be.ok
+
+      it 'does not match TextMessages', ->
+        callback = sinon.spy()
+        testMessage = new TextMessage(@user, 'message123')
+
+        @robot.enter(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.not.be.ok
+
+    describe '#leave', ->
+      it 'matches LeaveMessages', ->
+        callback = sinon.spy()
+        testMessage = new LeaveMessage(@user)
+
+        @robot.leave(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.be.ok
+
+      it 'does not match TextMessages', ->
+        callback = sinon.spy()
+        testMessage = new TextMessage(@user, 'message123')
+
+        @robot.leave(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.not.be.ok
+
+    describe '#topic', ->
+      it 'matches TopicMessages', ->
+        callback = sinon.spy()
+        testMessage = new TopicMessage(@user)
+
+        @robot.topic(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.be.ok
+
+      it 'does not match TextMessages', ->
+        callback = sinon.spy()
+        testMessage = new TextMessage(@user, 'message123')
+
+        @robot.topic(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.not.be.ok
+
+    describe '#catchAll', ->
+      it 'matches CatchAllMessages', ->
+        callback = sinon.spy()
+        testMessage = new CatchAllMessage(new TextMessage(@user, 'message123'))
+
+        @robot.catchAll(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.be.ok
+
+      it 'does not match TextMessages', ->
+        callback = sinon.spy()
+        testMessage = new TextMessage(@user, 'message123')
+
+        @robot.catchAll(callback)
+        testListener = @robot.listeners[0]
+        result = testListener.matcher(testMessage)
+
+        expect(result).to.not.be.ok
+
   describe 'Message Processing', ->
     it 'calls a matching listener', (done) ->
       testMessage = new TextMessage(@user, 'message123')


# Hubot classes
Robot = require '../src/robot.coffee'
{ CatchAllMessage, EnterMessage, TextMessage } = require '../src/message'
Adapter = require '../src/adapter'

# Preload the Hubot mock adapter but substitute in the latest version of Adapter

   @robot.shutdown()

  describe 'Unit Tests', ->
    describe '#hear', ->
      it 'registers a new listener', ->
        expect(@robot.listeners).to.have.length(0)
        @robot.hear /.*/, ->
        expect(@robot.listeners).to.have.length(1)

    describe '#respond', ->
      it 'registers a new listener', ->
        expect(@robot.listeners).to.have.length(0)
        @robot.respond /.*/, ->
        expect(@robot.listeners).to.have.length(1)

    describe '#enter', ->
      it 'registers a new listener', ->
        expect(@robot.listeners).to.have.length(0)
        @robot.enter ->
        expect(@robot.listeners).to.have.length(1)

    describe '#leave', ->
      it 'registers a new listener', ->
        expect(@robot.listeners).to.have.length(0)
        @robot.leave ->
        expect(@robot.listeners).to.have.length(1)

    describe '#topic', ->
      it 'registers a new listener', ->
        expect(@robot.listeners).to.have.length(0)
        @robot.topic ->
        expect(@robot.listeners).to.have.length(1)

    describe '#catchAll', ->
      it 'registers a new listener', ->
        expect(@robot.listeners).to.have.length(0)
        @robot.catchAll ->
        expect(@robot.listeners).to.have.length(1)

    describe '#receive', ->
      it 'calls all registered listeners', ->
        # Need to use a real Message so that the CatchAllMessage constructor works
