text: 
  /*!
   * socket.io-node
   * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
   * MIT Licensed
   */
  
  /**
   * Test dependencies.
   */
  
  var sio = require('../')
    , should = require('./common')
    , parser = sio.parser
    , ports = 15800;
  
  /**
   * Tests.
   */
  
  module.exports = {
    'websocket identifies as websocket': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , ws;
  
      io.set('transports', ['websocket']);
      io.on('connection', function (socket) {
        socket.manager.transports[socket.id].name.should.equal('websocket');
        ws.finishClose();
        cl.end();
        io.server.close();
        done();
      });
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
      });
    },
  
    'default websocket draft parser is used for unknown sec-websocket-version': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , ws;
  
      io.set('transports', ['websocket']);
      io.sockets.on('connection', function (socket) {
        socket.manager.transports[socket.id].protocolVersion.should.equal('hixie-76');
        ws.finishClose();
        cl.end();
        io.server.close();
        done();
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
      });
    },
  
    'hybi-07-12 websocket draft parser is used for sec-websocket-version: 8': function (done) {
      var cl = client(++ports)
        , io = create(cl);
  
      io.set('transports', ['websocket']);
      io.sockets.on('connection', function (socket) {
        socket.manager.transports[socket.id].protocolVersion.should.equal('07-12');
        cl.end();
        io.server.close();
        done();
      });
  
      var headers = {
        'sec-websocket-version': 8,
        'upgrade': 'websocket',
        'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
      }
  
      cl.get('/socket.io/{protocol}', {}, function (res, data) {
        var sid = data.split(':')[0];
        var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
        cl.get(url, {headers: headers}, function (res, data) {});
      });
    },
  
    'hybi-16 websocket draft parser is used for sec-websocket-version: 13': function (done) {
      var cl = client(++ports)
        , io = create(cl)
  
      io.set('transports', ['websocket']);
  
      io.sockets.on('connection', function (socket) {
        socket.manager.transports[socket.id].protocolVersion.should.equal('16');
        cl.end();
        io.server.close();
        done();
      });
  
      var headers = {
        'sec-websocket-version': 13,
        'upgrade': 'websocket',
        'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
      }
  
      cl.get('/socket.io/{protocol}', {}, function (res, data) {
        var sid = data.split(':')[0];
        var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
        cl.get(url, {headers: headers}, function (res, data) {});
      });
    },
  
    'hybi-07-12 origin filter blocks access for mismatched sec-websocket-origin': function (done) {
      var cl = client(++ports)
        , io = create(cl)
  
      io.set('transports', ['websocket']);
      io.set('origins', 'foo.bar.com:*');
      var notConnected = true;
      io.sockets.on('connection', function() {
          notConnected = false;
      });
  
      var headers = {
        'sec-websocket-version': 8,
        'upgrade': 'websocket',
        'Sec-WebSocket-Origin': 'http://baz.bar.com',
        'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
      }
  
      // handshake uses correct origin -- we want to block the actual websocket call
      cl.get('/socket.io/{protocol}', {headers: {origin: 'http://foo.bar.com'}}, function (res, data) {
        var sid = data.split(':')[0];
        var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
        var req = cl.get(url, {headers: headers}, function (res, data) {});
        var closed = false;
        (req.socket || req).on('close', function() {
          if (closed) return;
          closed = true;
          notConnected.should.be.true;
          cl.end();
          try {
            io.server.close();
          }
          catch (e) {}
          done();
        });
      });
    },
  
    'hybi-16 origin filter blocks access for mismatched sec-websocket-origin': function (done) {
      var cl = client(++ports)
        , io = create(cl);
  
      io.set('transports', ['websocket']);
      io.set('origins', 'foo.bar.com:*');
      var notConnected = true;
      io.sockets.on('connection', function() {
          notConnected = false;
      });
  
      var headers = {
        'sec-websocket-version': 13,
        'upgrade': 'websocket',
        'origin': 'http://baz.bar.com',
        'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
      }
  
      // handshake uses correct origin -- we want to block the actual websocket call
      cl.get('/socket.io/{protocol}', {headers: {origin: 'http://foo.bar.com'}}, function (res, data) {
        var sid = data.split(':')[0];
        var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
        var req = cl.get(url, {headers: headers}, function (res, data) {});
        var closed = false;
        (req.socket || req).on('close', function() {
          if (closed) return;
          closed = true;
          notConnected.should.be.true;
          cl.end();
          try {
            io.server.close();
          }
          catch (e) {}
          done();
        });
      });
    },
  
    'hybi-07-12 origin filter accepts implicit port 80 for sec-websocket-origin': function (done) {
  done();return;
      var cl = client(++ports)
        , io = create(cl)
  
      io.set('transports', ['websocket']);
      io.set('origins', 'foo.bar.com:80');
  
      var headers = {
        'sec-websocket-version': 8,
        'upgrade': 'websocket',
        'Sec-WebSocket-Origin': 'http://foo.bar.com',
        'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
      }
  
      io.sockets.on('connection', function() {
          cl.end();
          io.server.close();
          done();
      });
  
      // handshake uses correct origin -- we want to block the actual websocket call
      cl.get('/socket.io/{protocol}', {headers: {origin: 'http://foo.bar.com'}}, function (res, data) {
        var sid = data.split(':')[0];
        var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
        cl.get(url, {headers: headers}, function (res, data) {});
      });
    },
  
    'hybi-16 origin filter accepts implicit port 80 for sec-websocket-origin': function (done) {
      var cl = client(++ports)
        , io = create(cl)
  
      io.set('transports', ['websocket']);
      io.set('origins', 'foo.bar.com:80');
  
      var headers = {
        'sec-websocket-version': 13,
        'upgrade': 'websocket',
        'origin': 'http://foo.bar.com',
        'Sec-WebSocket-Key': 'dGhlIHNhbXBsZSBub25jZQ=='
      }
  
      io.sockets.on('connection', function() {
          cl.end();
          io.server.close();
          done();
      });
  
      // handshake uses correct origin -- we want to block the actual websocket call
      cl.get('/socket.io/{protocol}', {headers: {origin: 'http://foo.bar.com'}}, function (res, data) {
        var sid = data.split(':')[0];
        var url = '/socket.io/' + sio.protocol + '/websocket/' + sid;
        cl.get(url, {headers: headers}, function (res, data) {});
      });
    },
  
    'test that not responding to a heartbeat drops client': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , messages = 0
        , ws;
  
      io.configure(function () {
        io.set('heartbeat interval', .05);
        io.set('heartbeat timeout', .05);
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.on('disconnect', function (reason) {
          beat.should.be.true;
          reason.should.eql('heartbeat timeout');
  
          cl.end();
          ws.finishClose();
          io.server.close();
          done();
        });
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        ws.on('message', function (packet) {
          if (++messages == 1) {
            packet.type.should.eql('connect');
          } else {
            packet.type.should.eql('heartbeat');
            beat = true;
          }
        });
      });
    },
  
    'test that responding to a heartbeat maintains session': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , messages = 0
        , heartbeats = 0
        , ws;
  
      io.configure(function () {
        io.set('heartbeat interval', .05);
        io.set('heartbeat timeout', .05);
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.on('disconnect', function (reason) {
          heartbeats.should.eql(2);
          reason.should.eql('heartbeat timeout');
  
          cl.end();
          ws.finishClose();
          io.server.close();
          done();
        });
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        ws.on('message', function (packet) {
          if (++messages == 1) {
            packet.type.should.eql('connect');
          } else {
            packet.type.should.eql('heartbeat');
            heartbeats++;
  
            if (heartbeats == 1) {
              ws.packet({ type: 'heartbeat' });
            }
          }
        });
      });
    },
  
    'test sending deliverable volatile messages': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , messages = 0
        , messaged = false;
  
      io.configure(function () {
        io.set('close timeout', .05);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.volatile.send('tobi');
  
        socket.on('disconnect', function () {
          messaged.should.be.true;
          cl.end();
          io.server.close();
          done();
        });
      });
  
      cl.handshake(function (sid) {
        var ws = websocket(cl, sid);
        ws.on('message', function (msg) {
          if (++messages == 1) {
            msg.type.should.eql('connect');
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'tobi'
              , endpoint: ''
            });
            messaged = true;
            ws.finishClose();
          }
        });
      });
    },
  
    'test sending deliverable volatile json': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , messaged = false;
  
      io.configure(function () {
        io.set('close timeout', .05);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.volatile.json.send([1, 2, 3]);
  
        socket.on('disconnect', function () {
          messaged.should.be.true;
          cl.end();
          io.server.close();
          done();
        });
      });
  
      cl.handshake(function (sid) {
        var ws = websocket(cl, sid);
        ws.on('message', function (msg) {
          if (!ws.connected) {
            msg.type.should.eql('connect');
            ws.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: [1, 2, 3]
              , endpoint: ''
            });
            messaged = true;
            ws.finishClose();
          }
        });
      });
    },
  
    'test sending deliverable volatile events': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , messaged = false;
  
      io.configure(function () {
        io.set('close timeout', .05);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.volatile.emit('tobi');
  
        socket.on('disconnect', function () {
          messaged.should.be.true;
          cl.end();
          io.server.close();
          done();
        });
      });
  
      cl.handshake(function (sid) {
        var ws = websocket(cl, sid);
        ws.on('message', function (msg) {
          if (!ws.connected) {
            msg.type.should.eql('connect');
            ws.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'tobi'
              , endpoint: ''
              , args: []
            });
            messaged = true;
            ws.finishClose();
          }
        });
      });
    },
  
    'test sending to all clients in a namespace': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , io = create(cl1)
        , messages = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections == 2) {
          io.sockets.send('yup');
        }
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 2) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'yup'
              , endpoint: ''
            });
  
            messages++;
            ws1.finishClose();
          }
        });
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'yup'
              , endpoint: ''
            });
  
            messages++;
            ws2.finishClose();
          }
        });
      });
    },
  
    'test sending json to all clients in a namespace': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , io = create(cl1)
        , messages = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections == 2) {
          io.sockets.json.send({ a: 'b' });
        }
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 2) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: { a: 'b' }
              , endpoint: ''
            });
  
            messages++;
            ws1.finishClose();
          }
        });
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: { a: 'b' }
              , endpoint: ''
            });
  
            messages++;
            ws2.finishClose();
          }
        });
      });
    },
  
    'test emitting to all clients in a namespace': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , io = create(cl1)
        , messages = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections == 2) {
          io.sockets.emit('tobi', 'rapture');
        }
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 2) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'tobi'
              , args: ['rapture']
              , endpoint: ''
            });
  
            messages++;
            ws1.finishClose();
          }
        });
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'tobi'
              , args: ['rapture']
              , endpoint: ''
            });
  
            messages++;
            ws2.finishClose();
          }
        });
      });
    },
  
    'test sending to all clients in a room': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , joins = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections != 3) {
          socket.join('woot');
          joins++;
  
          if (joins == 2) {
            setTimeout(function () {
              connections.should.eql(3);
              io.sockets.in('woot').send('hahaha');
            }, 20);
          }
        }
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'hahaha'
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws1.finishClose();
        }, 50);
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'hahaha'
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws2.finishClose();
        }, 50);
      });
  
      cl3.handshake(function (sid) {
        var ws3 = websocket(cl3, sid);
        ws3.on('message', function (msg) {
          if (!ws3.connected) {
            msg.type.should.eql('connect');
            ws3.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'hahaha'
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws3.finishClose();
        }, 50);
      });
    },
  
    'test sending json to all clients in a room': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , joins = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections != 3) {
          socket.join('woot');
          joins++;
  
          if (joins == 2) {
            setTimeout(function () {
              connections.should.eql(3);
              io.sockets.in('woot').json.send(123);
            }, 20);
          }
        }
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: 123
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws1.finishClose();
        }, 50);
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: 123
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws2.finishClose();
        }, 50);
      });
  
      cl3.handshake(function (sid) {
        var ws3 = websocket(cl3, sid);
        ws3.on('message', function (msg) {
          if (!ws3.connected) {
            msg.type.should.eql('connect');
            ws3.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: 123
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws3.finishClose();
        }, 50);
      });
    },
  
    'test emitting to all clients in a room': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , joins = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections != 3) {
          socket.join('woot');
          joins++;
  
          if (joins == 2) {
            setTimeout(function () {
              connections.should.eql(3);
              io.sockets.in('woot').emit('locki');
            }, 20);
          }
        }
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'locki'
              , args: []
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws1.finishClose();
        }, 50);
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'locki'
              , args: []
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws2.finishClose();
        }, 50);
      });
  
      cl3.handshake(function (sid) {
        var ws3 = websocket(cl3, sid);
        ws3.on('message', function (msg) {
          if (!ws3.connected) {
            msg.type.should.eql('connect');
            ws3.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'locki'
              , args: []
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        setTimeout(function () {
          ws3.finishClose();
        }, 50);
      });
    },
  
    'test leaving a room': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , io = create(cl1)
        , joins = 0
        , disconnects = 0;
  
      io.set('close timeout', 0);
  
      io.sockets.on('connection', function (socket) {
        socket.join('foo');
        io.sockets.clients('foo').should.have.length(++joins);
  
        socket.on('disconnect', function () {
          socket.leave('foo');
          socket.leave('foo');
          socket.leave('foo');
  
          io.sockets.clients('foo').should.have.length(--joins);
  
          if (++disconnects == 2) {
            io.server.close();
            cl1.end();
            cl2.end();
            done();
          }
        })
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
             ws1.finishClose();
          }
        });
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
            ws2.finishClose();
          }
        });
      });
    },
  
    'test message with broadcast flag': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.on('trigger broadcast', function () {
          socket.broadcast.send('boom');
        });
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'boom'
              , endpoint: ''
            });
  
            messages++;
            ws1.finishClose();
          }
        });
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'boom'
              , endpoint: ''
            });
  
            messages++;
            ws2.finishClose();
          }
        });
      });
  
      cl3.handshake(function (sid) {
        var ws3 = websocket(cl3, sid);
        ws3.on('open', function () {
          ws3.packet({
              type: 'event'
            , name: 'trigger broadcast'
            , endpoint: ''
          });
  
          setTimeout(function () {
            ws3.finishClose();
          }, 50);
        });
  
        ws3.on('message', function (msg) {
          if (!ws3.connected) {
            msg.type.should.eql('connect');
            ws3.connected = true;
          } else {
            throw new Error('we shouldnt get a message here');
          }
        });
      });
    },
  
    'test json with broadcast flag': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.on('trigger broadcast', function () {
          socket.broadcast.json.send([1, 2, 3]);
        });
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: [1, 2, 3]
              , endpoint: ''
            });
  
            messages++;
            ws1.finishClose();
          }
        });
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: [1, 2, 3]
              , endpoint: ''
            });
  
            messages++;
            ws2.finishClose();
          }
        });
      });
  
      cl3.handshake(function (sid) {
        var ws3 = websocket(cl3, sid);
        ws3.on('open', function () {
          ws3.packet({
              type: 'event'
            , name: 'trigger broadcast'
            , endpoint: ''
          });
  
          setTimeout(function () {
            ws3.finishClose();
          }, 50);
        });
  
        ws3.on('message', function (msg) {
          if (!ws3.connected) {
            msg.type.should.eql('connect');
            ws3.connected = true;
          } else {
            throw new Error('we shouldnt get a message here');
          }
        });
      });
    },
  
    'test event with broadcast flag': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        socket.on('trigger broadcast', function () {
          socket.broadcast.emit('hey', 'arnold');
        });
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(2);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'hey'
              , args: ['arnold']
              , endpoint: ''
            });
  
            messages++;
            ws1.finishClose();
          }
        });
      });
  
      cl2.handshake(function (sid) {
        var ws2 = websocket(cl2, sid);
        ws2.on('message', function (msg) {
          if (!ws2.connected) {
            msg.type.should.eql('connect');
            ws2.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'hey'
              , args: ['arnold']
              , endpoint: ''
            });
  
            messages++;
            ws2.finishClose();
          }
        });
      });
  
      cl3.handshake(function (sid) {
        var ws3 = websocket(cl3, sid);
        ws3.on('open', function () {
          ws3.packet({
              type: 'event'
            , name: 'trigger broadcast'
            , endpoint: ''
          });
  
          setTimeout(function () {
            ws3.finishClose();
          }, 50);
        });
  
        ws3.on('message', function (msg) {
          if (!ws3.connected) {
            msg.type.should.eql('connect');
            ws3.connected = true;
          } else {
            throw new Error('we shouldnt get a message here');
          }
        });
      });
    },
  
    'test message with broadcast flag and to()': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections == 1) {
          socket.join('losers');
        }
  
        socket.on('trigger broadcast', function () {
          socket.broadcast.to('losers').send('boom');
        });
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(1);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'message'
              , data: 'boom'
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        ws1.on('open', function () {
          cl2.handshake(function (sid) {
            var ws2 = websocket(cl2, sid);
            ws2.on('message', function (msg) {
              if (!ws2.connected) {
                msg.type.should.eql('connect');
                ws2.connected = true;
              } else {
                throw new Error('This socket shouldnt get a message');
              }
            });
  
            ws2.on('open', function () {
              cl3.handshake(function (sid) {
                var ws3 = websocket(cl3, sid);
                ws3.on('open', function () {
                  ws3.packet({
                      type: 'event'
                    , name: 'trigger broadcast'
                    , endpoint: ''
                  });
  
                  setTimeout(function () {
                    ws1.finishClose();
                    ws2.finishClose();
                    ws3.finishClose();
                  }, 50);
                });
  
                ws3.on('message', function (msg) {
                  if (!ws3.connected) {
                    msg.type.should.eql('connect');
                    ws3.connected = true;
                  } else {
                    throw new Error('we shouldnt get a message here');
                  }
                });
              });
            });
          });
        });
      });
    },
  
    'test json with broadcast flag and to()': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections == 1) {
          socket.join('losers');
        }
  
        socket.on('trigger broadcast', function () {
          socket.broadcast.json.to('losers').send({ hello: 'world' });
        });
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(1);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'json'
              , data: { hello: 'world' }
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        ws1.on('open', function () {
          cl2.handshake(function (sid) {
            var ws2 = websocket(cl2, sid);
            ws2.on('message', function (msg) {
              if (!ws2.connected) {
                msg.type.should.eql('connect');
                ws2.connected = true;
              } else {
                throw new Error('This socket shouldnt get a message');
              }
            });
  
            ws2.on('open', function () {
              cl3.handshake(function (sid) {
                var ws3 = websocket(cl3, sid);
                ws3.on('open', function () {
                  ws3.packet({
                      type: 'event'
                    , name: 'trigger broadcast'
                    , endpoint: ''
                  });
  
                  setTimeout(function () {
                    ws1.finishClose();
                    ws2.finishClose();
                    ws3.finishClose();
                  }, 50);
                });
  
                ws3.on('message', function (msg) {
                  if (!ws3.connected) {
                    msg.type.should.eql('connect');
                    ws3.connected = true;
                  } else {
                    throw new Error('we shouldnt get a message here');
                  }
                });
              });
            });
          });
        });
      });
    },
  
    'test event with broadcast flag and to()': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , cl3 = client(port)
        , io = create(cl1)
        , messages = 0
        , connections = 0
        , disconnections = 0;
  
      io.configure(function () {
        io.set('close timeout', 0);
      });
  
      io.sockets.on('connection', function (socket) {
        connections++;
  
        if (connections == 1) {
          socket.join('losers');
        }
  
        socket.on('trigger broadcast', function () {
          socket.broadcast.to('losers').emit('victory');
        });
  
        socket.on('disconnect', function () {
          disconnections++;
  
          if (disconnections == 3) {
            messages.should.eql(1);
            cl1.end();
            cl2.end();
            cl3.end();
            io.server.close();
            done();
          }
        });
      });
  
      cl1.handshake(function (sid) {
        var ws1 = websocket(cl1, sid);
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
          } else {
            msg.should.eql({
                type: 'event'
              , name: 'victory'
              , args: []
              , endpoint: ''
            });
  
            messages++;
          }
        });
  
        ws1.on('open', function () {
          cl2.handshake(function (sid) {
            var ws2 = websocket(cl2, sid);
            ws2.on('message', function (msg) {
              if (!ws2.connected) {
                msg.type.should.eql('connect');
                ws2.connected = true;
              } else {
                throw new Error('This socket shouldnt get a message');
              };
            });
  
            ws2.on('open', function () {
              cl3.handshake(function (sid) {
                var ws3 = websocket(cl3, sid);
                ws3.on('open', function () {
                  ws3.packet({
                      type: 'event'
                    , name: 'trigger broadcast'
                    , endpoint: ''
                  });
  
                  setTimeout(function () {
                    ws1.finishClose();
                    ws2.finishClose();
                    ws3.finishClose();
                  }, 50);
                });
  
                ws3.on('message', function (msg) {
                  if (!ws3.connected) {
                    msg.type.should.eql('connect');
                    ws3.connected = true;
                  } else {
                    throw new Error('we shouldnt get a message here');
                  }
                });
              });
            });
          });
        });
      });
    },
  
    'test accessing handshake data from sockets': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , ws;
  
      io.sockets.on('connection', function (socket) {
        (!!socket.handshake.address.address).should.be.true;
        (!!socket.handshake.address.port).should.be.true;
        socket.handshake.headers.host.should.equal('localhost');
        socket.handshake.headers.connection.should.equal('keep-alive');
        socket.handshake.time.should.match(/GMT/);
  
        socket.on('disconnect', function () {
          setTimeout(function () {
            ws.finishClose();
            cl.end();
            io.server.close();
            done();
          }, 10);
        });
  
        socket.disconnect();
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        ws.on('message', function (msg) {
          if (!ws.connected) {
            msg.type.should.eql('connect');
            ws.connected = true;
          }
        });
      });
    },
  
    'test accessing the array of clients': function (done) {
      var port = ++ports
        , cl1 = client(port)
        , cl2 = client(port)
        , io = create(cl1)
        , total = 2
        , ws1, ws2;
  
      io.sockets.on('connection', function (socket) {
        socket.on('join ferrets', function () {
          socket.join('ferrets');
          socket.send('done');
        });
      });
  
      function check() {
        io.sockets.clients('ferrets').should.have.length(1);
        io.sockets.clients('ferrets')[0].should.be.an.instanceof(sio.Socket);
        io.sockets.clients('ferrets')[0].id.should.equal(ws1.sid);
        io.sockets.clients().should.have.length(2);
        io.sockets.clients()[0].should.be.an.instanceof(sio.Socket);
        io.sockets.clients()[0].id.should.equal(ws1.sid);
        io.sockets.clients()[1].should.be.an.instanceof(sio.Socket);
        io.sockets.clients()[1].id.should.equal(ws2.sid);
  
        ws1.finishClose();
        ws2.finishClose();
        cl1.end();
        cl2.end();
        io.server.close();
        done();
      };
  
      cl1.handshake(function (sid) {
        ws1 = websocket(cl1, sid);
        ws1.sid = sid;
        ws1.on('message', function (msg) {
          if (!ws1.connected) {
            msg.type.should.eql('connect');
            ws1.connected = true;
            ws1.packet({
                type: 'event'
              , name: 'join ferrets'
              , endpoint: ''
            });
          } else {
            cl2.handshake(function (sid) {
              ws2 = websocket(cl2, sid);
              ws2.sid = sid;
              ws2.on('message', function (msg) {
                if (!ws2.connected) {
                  msg.type.should.eql('connect');
                  ws2.connected = true;
                  check();
                }
              });
            });
          }
        });
      });
    },
  
    'test accessing handshake data from sockets on disconnect': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , ws;
  
      io.sockets.on('connection', function (socket) {
        socket.on('disconnect', function () {
  
        (!!socket.handshake.address.address).should.be.true;
        (!!socket.handshake.address.port).should.be.true;
        socket.handshake.headers.host.should.equal('localhost');
        socket.handshake.headers.connection.should.equal('keep-alive');
        socket.handshake.time.should.match(/GMT/);
  
          setTimeout(function () {
            ws.finishClose();
            cl.end();
            io.server.close();
            done();
          }, 10);
        });
  
        socket.disconnect();
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        ws.on('message', function (msg) {
          if (!ws.connected) {
            msg.type.should.eql('connect');
            ws.connected = true;
          }
        });
      });
    },
  
    'test for intentional and unintentional disconnects': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , calls = 0
        , ws;
  
      function close () {
        cl.end();
        io.server.close();
        ws.finishClose();
        done();
      }
  
      io.configure(function () {
        io.set('heartbeat interval', .05);
        io.set('heartbeat timeout', .05);
        io.set('close timeout', 0);
      });
  
      io.of('/foo').on('connection', function (socket) {
        socket.on('disconnect', function (reason) {
         reason.should.equal('packet');
  
         if (++calls == 2) close();
        });
      });
  
      io.of('/bar').on('connection', function (socket) {
        socket.on('disconnect', function (reason) {
          reason.should.equal('socket end');
  
          if (++calls == 2) close();
        });
      });
  
      cl.handshake(function (sid) {
        var messages = 0;
        ws = websocket(cl, sid);
        ws.on('open', function () {
          ws.packet({
              type: 'connect'
            , endpoint: '/foo'
          });
          ws.packet({
              type: 'connect'
            , endpoint: '/bar'
          });
        });
  
        ws.on('message', function (packet) {
          if (packet.type == 'connect') {
            if (++messages === 3) {
              ws.packet({ type: 'disconnect', endpoint:'/foo' });
              ws.finishClose();
            }
          }
        });
      });
    },
  
    'test socket clean up': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , ws;
  
      io.sockets.on('connection', function (socket) {
        var self = this
          , id = socket.id;
  
        socket.on('disconnect', function () {
          setTimeout(function () {
            var available = !!self.sockets[id];
  
            available.should.be.false;
            ws.finishClose();
            cl.end();
            io.server.close();
            done();
          }, 10);
        });
  
        socket.disconnect();
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        ws.on('message', function (msg) {
          if (!ws.connected) {
            msg.type.should.eql('connect');
            ws.connected = true;
          }
        });
      });
    },
  
    'accessing the transport type': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , ws;
  
      io.sockets.on('connection', function (socket) {
        socket.transport.should.equal('websocket');
  
        socket.on('disconnect', function () {
          setTimeout(function () {
            ws.finishClose();
            cl.end();
            io.server.close();
            done();
          }, 10);
        });
  
        socket.disconnect();
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        ws.on('message', function (msg) {
          if (!ws.connected) {
            msg.type.should.eql('connect');
            ws.connected = true;
          }
        });
      });
    },
    'disconnect when receiving too much data from the client': function (done) {
      var cl = client(++ports)
        , io = create(cl)
        , ws;
  
      io.set('transports', ['websocket']);
      io.set('destroy buffer size', 100);
      io.sockets.on('connection', function (socket) {
        socket.transport.should.equal('websocket');
  
        socket.on('disconnect', function () {
          setTimeout(function () {
            ws.finishClose();
            cl.end();
            io.server.close();
            done();
          }, 10);
        });
      });
  
      cl.handshake(function (sid) {
        ws = websocket(cl, sid);
        ws.on('open', function() {
          var bigMessage = new Buffer(200);
          bigMessage.fill('x');
          ws.write('3:3000::' + bigMessage);
        });
      });
    }
  
  };
  