PageRenderTime 226ms CodeModel.GetById 20ms app.highlight 192ms RepoModel.GetById 2ms app.codeStats 1ms

/test/socket.io.js

https://github.com/eheb/socket.io
JavaScript | 1383 lines | 1239 code | 137 blank | 7 comment | 55 complexity | 08d131d76761cd6f1afa398bde393da2 MD5 | raw file
Possible License(s): MIT
   1
   2var http = require('http').Server;
   3var io = require('..');
   4var fs = require('fs');
   5var join = require('path').join;
   6var ioc = require('socket.io-client');
   7var request = require('supertest');
   8var expect = require('expect.js');
   9
  10// creates a socket.io client for the given server
  11function client(srv, nsp, opts){
  12  if ('object' == typeof nsp) {
  13    opts = nsp;
  14    nsp = null;
  15  }
  16  var addr = srv.address();
  17  if (!addr) addr = srv.listen().address();
  18  var url = 'ws://' + addr.address + ':' + addr.port + (nsp || '');
  19  return ioc(url, opts);
  20}
  21
  22describe('socket.io', function(){
  23
  24  it('should be the same version as client', function(){
  25    var version = require('../package').version;
  26    expect(version).to.be(require('socket.io-client/package').version);
  27  });
  28
  29  describe('set', function() {
  30    it('should be able to set ping timeout to engine.io', function() {
  31      var srv = io(http());
  32      srv.set('heartbeat timeout', 10);
  33      expect(srv.eio.pingTimeout).to.be(10);
  34    });
  35
  36    it('should be able to set ping interval to engine.io', function() {
  37      var srv = io(http());
  38      srv.set('heartbeat interval', 10);
  39      expect(srv.eio.pingInterval).to.be(10);
  40    });
  41
  42    it('should be able to set transports to engine.io', function() {
  43      var srv = io(http());
  44      srv.set('transports', ['polling']);
  45      expect(srv.eio.transports).to.eql(['polling']);
  46    });
  47
  48    it('should be able to set maxHttpBufferSize to engine.io', function() {
  49      var srv = io(http());
  50      srv.set('destroy buffer size', 10);
  51      expect(srv.eio.maxHttpBufferSize).to.eql(10);
  52    });
  53
  54    it('should be able to set path with setting resource', function() {
  55      var srv = io(http());
  56      srv.set('resource', '/random');
  57      expect(srv.path()).to.be('/random');
  58    });
  59
  60    it('should be able to set origins to engine.io', function() {
  61      var srv = io(http());
  62      srv.set('origins', 'http://hostname.com:*');
  63      expect(srv.origins()).to.be('http://hostname.com:*');
  64    });
  65
  66    it('should be able to set authorization and send error packet', function(done) {
  67      var httpSrv = http();
  68      var srv = io(httpSrv);
  69      srv.set('authorization', function(o, f) { f(null, false); });
  70
  71      var socket = client(httpSrv);
  72      socket.on('connect', function(){
  73        expect().fail();
  74      });
  75      socket.on('error', function(err) {
  76        expect(err).to.be('Not authorized');
  77        done();
  78      });
  79    });
  80
  81    it('should be able to set authorization and succeed', function(done) {
  82      var httpSrv = http();
  83      var srv = io(httpSrv);
  84      srv.set('authorization', function(o, f) { f(null, true); });
  85
  86      srv.on('connection', function(s) {
  87        s.on('yoyo', function(data) {
  88          expect(data).to.be('data');
  89          done();
  90        });
  91      });
  92
  93      var socket = client(httpSrv);
  94      socket.on('connect', function(){
  95        socket.emit('yoyo', 'data');
  96      });
  97
  98      socket.on('error', function(err) {
  99        expect().fail();
 100      });
 101    });
 102
 103    it('should set the handshake BC object', function(done){
 104      var httpSrv = http();
 105      var srv = io(httpSrv);
 106
 107      srv.on('connection', function(s) {
 108        expect(s.handshake).to.not.be(undefined);
 109
 110        // Headers set and has some valid properties
 111        expect(s.handshake.headers).to.be.an('object');
 112        expect(s.handshake.headers['user-agent']).to.be('node-XMLHttpRequest');
 113
 114        // Time set and is valid looking string
 115        expect(s.handshake.time).to.be.a('string');
 116        expect(s.handshake.time.split(' ').length > 0); // Is "multipart" string representation
 117
 118        // Address, xdomain, secure, issued and url set
 119        expect(s.handshake.address).to.not.be(undefined);
 120        expect(s.handshake.xdomain).to.be.a('boolean');
 121        expect(s.handshake.secure).to.be.a('boolean');
 122        expect(s.handshake.issued).to.be.a('number');
 123        expect(s.handshake.url).to.be.a('string');
 124
 125        // Query set and has some right properties
 126        expect(s.handshake.query).to.be.an('object');
 127        expect(s.handshake.query.EIO).to.not.be(undefined);
 128        expect(s.handshake.query.transport).to.not.be(undefined);
 129        expect(s.handshake.query.t).to.not.be(undefined);
 130
 131        done();
 132      });
 133
 134      var socket = client(httpSrv);
 135    });
 136  });
 137
 138  describe('server attachment', function(){
 139    describe('http.Server', function(){
 140      var clientVersion = require('socket.io-client/package').version;
 141
 142      it('should serve static files', function(done){
 143        var srv = http();
 144        io(srv);
 145        request(srv)
 146        .get('/socket.io/socket.io.js')
 147        .buffer(true)
 148        .end(function(err, res){
 149          if (err) return done(err);
 150          var ctype = res.headers['content-type'];
 151          expect(ctype).to.be('application/javascript');
 152          expect(res.headers.etag).to.be(clientVersion);
 153          expect(res.text).to.match(/engine\.io/);
 154          expect(res.status).to.be(200);
 155          done();
 156        });
 157      });
 158
 159      it('should handle 304', function(done){
 160        var srv = http();
 161        io(srv);
 162        request(srv)
 163        .get('/socket.io/socket.io.js')
 164        .set('If-None-Match', clientVersion)
 165        .end(function(err, res){
 166          if (err) return done(err);
 167          expect(res.statusCode).to.be(304);
 168          done();
 169        });
 170      });
 171
 172      it('should not serve static files', function(done){
 173        var srv = http();
 174        io(srv, { serveClient: false });
 175        request(srv)
 176        .get('/socket.io/socket.io.js')
 177        .expect(400, done);
 178      });
 179
 180      it('should work with #attach', function(done){
 181        var srv = http(function(req, res){
 182          res.writeHead(404);
 183          res.end();
 184        });
 185        var sockets = io();
 186        sockets.attach(srv);
 187        request(srv)
 188        .get('/socket.io/socket.io.js')
 189        .end(function(err, res){
 190          if (err) return done(err);
 191          expect(res.status).to.be(200);
 192          done();
 193        });
 194      });
 195    });
 196
 197    describe('port', function(done){
 198      it('should be bound', function(done){
 199        var sockets = io(54010);
 200        request('http://localhost:54010')
 201        .get('/socket.io/socket.io.js')
 202        .expect(200, done);
 203      });
 204
 205      it('should be bound as a string', function(done) {
 206        var sockets = io('54020');
 207        request('http://localhost:54020')
 208        .get('/socket.io/socket.io.js')
 209        .expect(200, done);
 210      });
 211
 212      it('with listen', function(done){
 213        var sockets = io().listen(54011);
 214        request('http://localhost:54011')
 215        .get('/socket.io/socket.io.js')
 216        .expect(200, done);
 217      });
 218
 219      it('as a string', function(done){
 220        var sockets = io().listen('54012');
 221        request('http://localhost:54012')
 222        .get('/socket.io/socket.io.js')
 223        .expect(200, done);
 224      });
 225    });
 226  });
 227
 228  describe('handshake', function(){
 229    var request = require('superagent');
 230
 231    it('should disallow request when origin defined and none specified', function(done) {
 232      var sockets = io({ origins: 'http://foo.example:*' }).listen('54013');
 233      request.get('http://localhost:54013/socket.io/default/')
 234       .query({ transport: 'polling' })
 235       .end(function (err, res) {
 236          expect(res.status).to.be(400);
 237          done();
 238        });
 239    });
 240
 241    it('should disallow request when origin defined and a different one specified', function(done) {
 242      var sockets = io({ origins: 'http://foo.example:*' }).listen('54014');
 243      request.get('http://localhost:54014/socket.io/default/')
 244       .query({ transport: 'polling' })
 245       .set('origin', 'http://herp.derp')
 246       .end(function (err, res) {
 247          expect(res.status).to.be(400);
 248          done();
 249       });
 250    });
 251
 252    it('should allow request when origin defined an the same is specified', function(done) {
 253      var sockets = io({ origins: 'http://foo.example:*' }).listen('54015');
 254      request.get('http://localhost:54015/socket.io/default/')
 255       .set('origin', 'http://foo.example')
 256       .query({ transport: 'polling' })
 257       .end(function (err, res) {
 258          expect(res.status).to.be(200);
 259          done();
 260        });
 261    });
 262  });
 263
 264  describe('close', function(){
 265
 266    it('should be able to close sio sending a srv', function(){
 267      var PORT   = 54016;
 268      var srv    = http().listen(PORT);
 269      var sio    = io(srv);
 270      var net    = require('net');
 271      var server = net.createServer();
 272
 273      var clientSocket = client(srv, { reconnection: false });
 274
 275      clientSocket.on('disconnect', function init() {
 276        expect(sio.nsps['/'].sockets.length).to.equal(0);
 277        server.listen(PORT);
 278      });
 279
 280      clientSocket.on('connect', function init() {
 281        expect(sio.nsps['/'].sockets.length).to.equal(1);
 282        sio.close();
 283      });
 284
 285      server.once('listening', function() {
 286        // PORT should be free
 287        server.close(function(error){
 288          expect(error).to.be(undefined);
 289        });
 290      });
 291
 292    });
 293
 294    it('should be able to close sio sending a port', function(){
 295      var PORT   = 54017;
 296      var sio    = io(PORT);
 297      var net    = require('net');
 298      var server = net.createServer();
 299
 300      var clientSocket = ioc('ws://0.0.0.0:' + PORT);
 301
 302      clientSocket.on('disconnect', function init() {
 303        expect(sio.nsps['/'].sockets.length).to.equal(0);
 304        server.listen(PORT);
 305      });
 306
 307      clientSocket.on('connect', function init() {
 308        expect(sio.nsps['/'].sockets.length).to.equal(1);
 309        sio.close();
 310      });
 311
 312      server.once('listening', function() {
 313        // PORT should be free
 314        server.close(function(error){
 315          expect(error).to.be(undefined);
 316        });
 317      });
 318    });
 319
 320  });
 321
 322  describe('namespaces', function(){
 323    var Socket = require('../lib/socket');
 324    var Namespace = require('../lib/namespace');
 325
 326    describe('default', function(){
 327      it('should be accessible through .sockets', function(){
 328        var sio = io();
 329        expect(sio.sockets).to.be.a(Namespace);
 330      });
 331
 332      it('should be aliased', function(){
 333        var sio = io();
 334        expect(sio.use).to.be.a('function');
 335        expect(sio.to).to.be.a('function');
 336        expect(sio['in']).to.be.a('function');
 337        expect(sio.emit).to.be.a('function');
 338        expect(sio.send).to.be.a('function');
 339        expect(sio.write).to.be.a('function');
 340      });
 341
 342      it('should automatically connect', function(done){
 343        var srv = http();
 344        var sio = io(srv);
 345        srv.listen(function(){
 346          var socket = client(srv);
 347          socket.on('connect', function(){
 348            done();
 349          });
 350        });
 351      });
 352
 353      it('should fire a `connection` event', function(done){
 354        var srv = http();
 355        var sio = io(srv);
 356        srv.listen(function(){
 357          var socket = client(srv);
 358          sio.on('connection', function(socket){
 359            expect(socket).to.be.a(Socket);
 360            done();
 361          });
 362        });
 363      });
 364
 365      it('should fire a `connect` event', function(done){
 366        var srv = http();
 367        var sio = io(srv);
 368        srv.listen(function(){
 369          var socket = client(srv);
 370          sio.on('connect', function(socket){
 371            expect(socket).to.be.a(Socket);
 372            done();
 373          });
 374        });
 375      });
 376
 377      it('should work with many sockets', function(done){
 378        var srv = http();
 379        var sio = io(srv);
 380        srv.listen(function(){
 381          var chat = client(srv, '/chat');
 382          var news = client(srv, '/news');
 383          var total = 2;
 384          chat.on('connect', function(){
 385            --total || done();
 386          });
 387          news.on('connect', function(){
 388            --total || done();
 389          });
 390        });
 391      });
 392
 393      it('should work with `of` and many sockets', function(done){
 394        var srv = http();
 395        var sio = io(srv);
 396        srv.listen(function(){
 397          var chat = client(srv, '/chat');
 398          var news = client(srv, '/news');
 399          var total = 2;
 400          sio.of('/news').on('connection', function(socket){
 401            expect(socket).to.be.a(Socket);
 402            --total || done();
 403          });
 404          sio.of('/news').on('connection', function(socket){
 405            expect(socket).to.be.a(Socket);
 406            --total || done();
 407          });
 408        });
 409      });
 410
 411      it('should work with `of` second param', function(done){
 412        var srv = http();
 413        var sio = io(srv);
 414        srv.listen(function(){
 415          var chat = client(srv, '/chat');
 416          var news = client(srv, '/news');
 417          var total = 2;
 418          sio.of('/news', function(socket){
 419            expect(socket).to.be.a(Socket);
 420            --total || done();
 421          });
 422          sio.of('/news', function(socket){
 423            expect(socket).to.be.a(Socket);
 424            --total || done();
 425          });
 426        });
 427      });
 428
 429      it('should disconnect upon transport disconnection', function(done){
 430        var srv = http();
 431        var sio = io(srv);
 432        srv.listen(function(){
 433          var chat = client(srv, '/chat');
 434          var news = client(srv, '/news');
 435          var total = 2;
 436          var totald = 2;
 437          var s;
 438          sio.of('/news', function(socket){
 439            socket.on('disconnect', function(reason){
 440              --totald || done();
 441            });
 442            --total || close();
 443          });
 444          sio.of('/chat', function(socket){
 445            s = socket;
 446            socket.on('disconnect', function(reason){
 447              --totald || done();
 448            });
 449            --total || close();
 450          });
 451          function close(){
 452            s.disconnect(true);
 453          }
 454        });
 455      });
 456
 457      it('should disconnect both default and custom namespace upon disconnect', function(done){
 458        var srv = http();
 459        var sio = io(srv);
 460        srv.listen(function(){
 461          var lolcats = client(srv, '/lolcats');
 462          var total = 2;
 463          var totald = 2;
 464          var s;
 465          sio.of('/', function(socket){
 466            socket.on('disconnect', function(reason){
 467              --totald || done();
 468            });
 469            --total || close();
 470          });
 471          sio.of('/lolcats', function(socket){
 472            s = socket;
 473            socket.on('disconnect', function(reason){
 474              --totald || done();
 475            });
 476            --total || close();
 477          });
 478          function close(){
 479            s.disconnect(true);
 480          }
 481        });
 482      });
 483    });
 484  });
 485
 486  describe('socket', function(){
 487
 488    it('should not fire events more than once after manually reconnecting', function(done) {
 489      var srv = http();
 490      var sio = io(srv);
 491      srv.listen(function(){
 492        var clientSocket = client(srv, { reconnection: false });
 493        clientSocket.on('connect', function init() {
 494          clientSocket.removeListener('connect', init);
 495          clientSocket.io.engine.close();
 496
 497          clientSocket.connect();
 498          clientSocket.on('connect', function() {
 499            done();
 500          });
 501        });
 502      });
 503    });
 504
 505    it('should not fire reconnect_failed event more than once when server closed', function(done) {
 506      var srv = http();
 507      var sio = io(srv);
 508      srv.listen(function(){
 509        var clientSocket = client(srv, { reconnectionAttempts: 3, reconnectionDelay: 10 });
 510        clientSocket.on('connect', function() {
 511          srv.close();
 512        });
 513
 514        clientSocket.on('reconnect_failed', function() {
 515          done();
 516        });
 517      });
 518    });
 519
 520    it('should receive events', function(done){
 521      var srv = http();
 522      var sio = io(srv);
 523      srv.listen(function(){
 524        var socket = client(srv);
 525        sio.on('connection', function(s){
 526          s.on('random', function(a, b, c){
 527            expect(a).to.be(1);
 528            expect(b).to.be('2');
 529            expect(c).to.eql([3]);
 530            done();
 531          });
 532          socket.emit('random', 1, '2', [3]);
 533        });
 534      });
 535    });
 536
 537    it('should receive message events through `send`', function(done){
 538      var srv = http();
 539      var sio = io(srv);
 540      srv.listen(function(){
 541        var socket = client(srv);
 542        sio.on('connection', function(s){
 543          s.on('message', function(a){
 544            expect(a).to.be(1337);
 545            done();
 546          });
 547          socket.send(1337);
 548        });
 549      });
 550    });
 551
 552    it('should emit events', function(done){
 553      var srv = http();
 554      var sio = io(srv);
 555      srv.listen(function(){
 556        var socket = client(srv);
 557        socket.on('woot', function(a){
 558          expect(a).to.be('tobi');
 559          done();
 560        });
 561        sio.on('connection', function(s){
 562          s.emit('woot', 'tobi');
 563        });
 564      });
 565    });
 566
 567    it('should emit events with utf8 multibyte character', function(done) {
 568      var srv = http();
 569      var sio = io(srv);
 570      srv.listen(function(){
 571        var socket = client(srv);
 572        var i = 0;
 573        socket.on('hoot', function(a){
 574          expect(a).to.be('utf8 — string');
 575          i++;
 576
 577          if (3 == i) {
 578            done();
 579          }
 580        });
 581        sio.on('connection', function(s){
 582          s.emit('hoot', 'utf8 — string');
 583          s.emit('hoot', 'utf8 — string');
 584          s.emit('hoot', 'utf8 — string');
 585        });
 586      });
 587    });
 588
 589    it('should emit events with binary data', function(done){
 590      var srv = http();
 591      var sio = io(srv);
 592      srv.listen(function(){
 593        var socket = client(srv);
 594        var imageData;
 595        socket.on('doge', function(a){
 596          expect(Buffer.isBuffer(a)).to.be(true);
 597          expect(imageData.length).to.equal(a.length);
 598          expect(imageData[0]).to.equal(a[0]);
 599          expect(imageData[imageData.length - 1]).to.equal(a[a.length - 1]);
 600          done();
 601        });
 602        sio.on('connection', function(s){
 603          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 604            if (err) return done(err);
 605            imageData = data;
 606            s.emit('doge', data);
 607          });
 608        });
 609      });
 610    });
 611
 612    it('should emit events with several types of data (including binary)', function(done){
 613      var srv = http();
 614      var sio = io(srv);
 615      srv.listen(function(){
 616        var socket = client(srv);
 617        socket.on('multiple', function(a, b, c, d, e, f){
 618          expect(a).to.be(1);
 619          expect(Buffer.isBuffer(b)).to.be(true);
 620          expect(c).to.be('3');
 621          expect(d).to.eql([4]);
 622          expect(Buffer.isBuffer(e)).to.be(true);
 623          expect(Buffer.isBuffer(f[0])).to.be(true);
 624          expect(f[1]).to.be('swag');
 625          expect(Buffer.isBuffer(f[2])).to.be(true);
 626          done();
 627        });
 628        sio.on('connection', function(s){
 629          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 630            if (err) return done(err);
 631            var buf = new Buffer('asdfasdf', 'utf8');
 632            s.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
 633          });
 634        });
 635      });
 636    });
 637
 638    it('should receive events with binary data', function(done){
 639      var srv = http();
 640      var sio = io(srv);
 641      srv.listen(function(){
 642        var socket = client(srv);
 643        sio.on('connection', function(s){
 644          s.on('buff', function(a){
 645            expect(Buffer.isBuffer(a)).to.be(true);
 646            done();
 647          });
 648          var buf = new Buffer('abcdefg', 'utf8');
 649          socket.emit('buff', buf);
 650        });
 651      });
 652    });
 653
 654    it('should receive events with several types of data (including binary)', function(done){
 655      var srv = http();
 656      var sio = io(srv);
 657      srv.listen(function(){
 658        var socket = client(srv);
 659        sio.on('connection', function(s){
 660          s.on('multiple', function(a, b, c, d, e, f){
 661          expect(a).to.be(1);
 662          expect(Buffer.isBuffer(b)).to.be(true);
 663          expect(c).to.be('3');
 664          expect(d).to.eql([4]);
 665          expect(Buffer.isBuffer(e)).to.be(true);
 666          expect(Buffer.isBuffer(f[0])).to.be(true);
 667          expect(f[1]).to.be('swag');
 668          expect(Buffer.isBuffer(f[2])).to.be(true);
 669          done();
 670          });
 671          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 672            if (err) return done(err);
 673            var buf = new Buffer('asdfasdf', 'utf8');
 674            socket.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
 675          });
 676        });
 677      });
 678    });
 679
 680    it('should emit message events through `send`', function(done){
 681      var srv = http();
 682      var sio = io(srv);
 683      srv.listen(function(){
 684        var socket = client(srv);
 685        socket.on('message', function(a){
 686          expect(a).to.be('a');
 687          done();
 688        });
 689        sio.on('connection', function(s){
 690          s.send('a');
 691        });
 692      });
 693    });
 694
 695    it('should receive event with callbacks', function(done){
 696      var srv = http();
 697      var sio = io(srv);
 698      srv.listen(function(){
 699        var socket = client(srv);
 700        sio.on('connection', function(s){
 701          s.on('woot', function(fn){
 702            fn(1, 2);
 703          });
 704          socket.emit('woot', function(a, b){
 705            expect(a).to.be(1);
 706            expect(b).to.be(2);
 707            done();
 708          });
 709        });
 710      });
 711    });
 712
 713    it('should receive all events emitted from namespaced client immediately and in order', function(done) {
 714      var srv = http();
 715      var sio = io(srv);
 716      var total = 0;
 717      srv.listen(function(){
 718        sio.of('/chat', function(s){
 719          s.on('hi', function(letter){
 720            total++;
 721            if (total == 2 && letter == 'b') {
 722              done();
 723            } else if (total == 1 && letter != 'a') {
 724              throw new Error('events out of order');
 725            }
 726          });
 727        });
 728
 729        var chat = client(srv, '/chat');
 730        chat.emit('hi', 'a');
 731        setTimeout(function() {
 732          chat.emit('hi', 'b');
 733        }, 50);
 734      });
 735    });
 736
 737    it('should emit events with callbacks', function(done){
 738      var srv = http();
 739      var sio = io(srv);
 740      srv.listen(function(){
 741        var socket = client(srv);
 742        sio.on('connection', function(s){
 743          socket.on('hi', function(fn){
 744            fn();
 745          });
 746          s.emit('hi', function(){
 747            done();
 748          });
 749        });
 750      });
 751    });
 752
 753    it('should receive events with args and callback', function(done){
 754      var srv = http();
 755      var sio = io(srv);
 756      srv.listen(function(){
 757        var socket = client(srv);
 758        sio.on('connection', function(s){
 759          s.on('woot', function(a, b, fn){
 760            expect(a).to.be(1);
 761            expect(b).to.be(2);
 762            fn();
 763          });
 764          socket.emit('woot', 1, 2, function(){
 765            done();
 766          });
 767        });
 768      });
 769    });
 770
 771    it('should emit events with args and callback', function(done){
 772      var srv = http();
 773      var sio = io(srv);
 774      srv.listen(function(){
 775        var socket = client(srv);
 776        sio.on('connection', function(s){
 777          socket.on('hi', function(a, b, fn){
 778            expect(a).to.be(1);
 779            expect(b).to.be(2);
 780            fn();
 781          });
 782          s.emit('hi', 1, 2, function(){
 783            done();
 784          });
 785        });
 786      });
 787    });
 788
 789    it('should receive events with binary args and callbacks', function(done) {
 790      var srv = http();
 791      var sio = io(srv);
 792      srv.listen(function(){
 793        var socket = client(srv);
 794        sio.on('connection', function(s){
 795          s.on('woot', function(buf, fn){
 796            expect(Buffer.isBuffer(buf)).to.be(true);
 797            fn(1, 2);
 798          });
 799          socket.emit('woot', new Buffer(3), function(a, b){
 800            expect(a).to.be(1);
 801            expect(b).to.be(2);
 802            done();
 803          });
 804        });
 805      });
 806    });
 807
 808    it('should emit events with binary args and callback', function(done){
 809      var srv = http();
 810      var sio = io(srv);
 811      srv.listen(function(){
 812        var socket = client(srv);
 813        sio.on('connection', function(s){
 814          socket.on('hi', function(a, fn){
 815            expect(Buffer.isBuffer(a)).to.be(true);
 816            fn();
 817          });
 818          s.emit('hi', new Buffer(4), function(){
 819            done();
 820          });
 821        });
 822      });
 823    });
 824
 825    it('should emit events and receive binary data in a callback', function(done) {
 826      var srv = http();
 827      var sio = io(srv);
 828      srv.listen(function(){
 829        var socket = client(srv);
 830        sio.on('connection', function(s){
 831          socket.on('hi', function(fn){
 832            fn(new Buffer(1));
 833          });
 834          s.emit('hi', function(a){
 835            expect(Buffer.isBuffer(a)).to.be(true);
 836            done();
 837          });
 838        });
 839      });
 840    });
 841
 842    it('should receive events and pass binary data in a callback', function(done) {
 843      var srv = http();
 844      var sio = io(srv);
 845      srv.listen(function(){
 846        var socket = client(srv);
 847        sio.on('connection', function(s){
 848          s.on('woot', function(fn){
 849            fn(new Buffer(2));
 850          });
 851          socket.emit('woot', function(a){
 852            expect(Buffer.isBuffer(a)).to.be(true);
 853            done();
 854          });
 855        });
 856      });
 857    });
 858
 859    it('should have access to the client', function(done){
 860      var srv = http();
 861      var sio = io(srv);
 862      srv.listen(function(){
 863        var socket = client(srv);
 864        sio.on('connection', function(s){
 865          expect(s.client).to.be.an('object');
 866          done();
 867        });
 868      });
 869    });
 870
 871    it('should have access to the connection', function(done){
 872      var srv = http();
 873      var sio = io(srv);
 874      srv.listen(function(){
 875        var socket = client(srv);
 876        sio.on('connection', function(s){
 877          expect(s.client.conn).to.be.an('object');
 878          expect(s.conn).to.be.an('object');
 879          done();
 880        });
 881      });
 882    });
 883
 884    it('should have access to the request', function(done){
 885      var srv = http();
 886      var sio = io(srv);
 887      srv.listen(function(){
 888        var socket = client(srv);
 889        sio.on('connection', function(s){
 890          expect(s.client.request.headers).to.be.an('object');
 891          expect(s.request.headers).to.be.an('object');
 892          done();
 893        });
 894      });
 895    });
 896
 897    it('should see query parameters in the request', function(done) {
 898      var srv = http();
 899      var sio = io(srv);
 900      srv.listen(function() {
 901        var addr = srv.listen().address();
 902        var url = 'ws://' + addr.address + ':' + addr.port + '?key1=1&key2=2';
 903        var socket = ioc(url);
 904        sio.on('connection', function(s) {
 905          var parsed = require('url').parse(s.request.url);
 906          var query = require('querystring').parse(parsed.query);
 907          expect(query.key1).to.be('1');
 908          expect(query.key2).to.be('2');
 909          done();
 910        });
 911      });
 912    });
 913
 914    it('should handle very large json', function(done){
 915      this.timeout();
 916      var srv = http();
 917      var sio = io(srv);
 918      var received = 0;
 919      srv.listen(function(){
 920        var socket = client(srv);
 921        socket.on('big', function(a){
 922          expect(Buffer.isBuffer(a.json)).to.be(false);
 923          if (++received == 3)
 924            done();
 925          else
 926            socket.emit('big', a);
 927        });
 928        sio.on('connection', function(s){
 929          fs.readFile(join(__dirname, 'fixtures', 'big.json'), function(err, data){
 930            if (err) return done(err);
 931            data = JSON.parse(data);
 932            s.emit('big', {hello: 'friend', json: data});
 933          });
 934          s.on('big', function(a){
 935            s.emit('big', a);
 936          });
 937        });
 938      });
 939    });
 940
 941    it('should handle very large binary data', function(done){
 942      var srv = http();
 943      var sio = io(srv);
 944      var received = 0;
 945      srv.listen(function(){
 946        var socket = client(srv);
 947        socket.on('big', function(a){
 948          expect(Buffer.isBuffer(a.image)).to.be(true);
 949          if (++received == 3)
 950            done();
 951          else
 952            socket.emit('big', a);
 953        });
 954        sio.on('connection', function(s){
 955          fs.readFile(join(__dirname, 'fixtures', 'big.jpg'), function(err, data){
 956            if (err) return done(err);
 957            s.emit('big', {hello: 'friend', image: data});
 958          });
 959          s.on('big', function(a){
 960            expect(Buffer.isBuffer(a.image)).to.be(true);
 961            s.emit('big', a);
 962          });
 963        });
 964      });
 965    });
 966  });
 967
 968  describe('messaging many', function(){
 969    it('emits to a namespace', function(done){
 970      var srv = http();
 971      var sio = io(srv);
 972      var total = 2;
 973
 974      srv.listen(function(){
 975        var socket1 = client(srv, { multiplex: false });
 976        var socket2 = client(srv, { multiplex: false });
 977        var socket3 = client(srv, '/test');
 978        socket1.on('a', function(a){
 979          expect(a).to.be('b');
 980          --total || done();
 981        });
 982        socket2.on('a', function(a){
 983          expect(a).to.be('b');
 984          --total || done();
 985        });
 986        socket3.on('a', function(){ done(new Error('not')); });
 987
 988        var sockets = 3;
 989        sio.on('connection', function(socket){
 990          --sockets || emit();
 991        });
 992        sio.of('/test', function(socket){
 993          --sockets || emit();
 994        });
 995
 996        function emit(){
 997          sio.emit('a', 'b');
 998        }
 999      });
1000    });
1001
1002    it('emits binary data to a namespace', function(done){
1003      var srv = http();
1004      var sio = io(srv);
1005      var total = 2;
1006
1007      srv.listen(function(){
1008        var socket1 = client(srv, { multiplex: false });
1009        var socket2 = client(srv, { multiplex: false });
1010        var socket3 = client(srv, '/test');
1011        socket1.on('bin', function(a){
1012          expect(Buffer.isBuffer(a)).to.be(true);
1013          --total || done();
1014        });
1015        socket2.on('bin', function(a){
1016          expect(Buffer.isBuffer(a)).to.be(true);
1017          --total || done();
1018        });
1019        socket3.on('bin', function(){ done(new Error('not')); });
1020
1021        var sockets = 3;
1022        sio.on('connection', function(socket){
1023          --sockets || emit();
1024        });
1025        sio.of('/test', function(socket){
1026          --sockets || emit();
1027        });
1028
1029        function emit(){
1030          sio.emit('bin', new Buffer(10));
1031        }
1032      });
1033    });
1034
1035    it('emits to the rest', function(done){
1036      var srv = http();
1037      var sio = io(srv);
1038      var total = 2;
1039
1040      srv.listen(function(){
1041        var socket1 = client(srv, { multiplex: false });
1042        var socket2 = client(srv, { multiplex: false });
1043        var socket3 = client(srv, '/test');
1044        socket1.on('a', function(a){
1045          expect(a).to.be('b');
1046          socket1.emit('finish');
1047        });
1048        socket2.emit('broadcast');
1049        socket2.on('a', function(){ done(new Error('done')); });
1050        socket3.on('a', function(){ done(new Error('not')); });
1051
1052        var sockets = 2;
1053        sio.on('connection', function(socket){
1054          socket.on('broadcast', function(){
1055            socket.broadcast.emit('a', 'b');
1056          });
1057          socket.on('finish', function(){
1058            done();
1059          });
1060        });
1061      });
1062    });
1063
1064    it('emits to rooms', function(done){
1065      var srv = http();
1066      var sio = io(srv);
1067      var total = 2;
1068
1069      srv.listen(function(){
1070        var socket1 = client(srv, { multiplex: false });
1071        var socket2 = client(srv, { multiplex: false });
1072
1073        socket2.on('a', function(){
1074          done(new Error('not'));
1075        });
1076        socket1.on('a', function(){
1077          done();
1078        });
1079        socket1.emit('join', 'woot', function(){
1080          socket1.emit('emit', 'woot');
1081        });
1082
1083        sio.on('connection', function(socket){
1084          socket.on('join', function(room, fn){
1085            socket.join(room, fn);
1086          });
1087
1088          socket.on('emit', function(room){
1089            sio.in(room).emit('a');
1090          });
1091        });
1092      });
1093    });
1094
1095    it('emits to rooms avoiding dupes', function(done){
1096      var srv = http();
1097      var sio = io(srv);
1098      var total = 2;
1099
1100      srv.listen(function(){
1101        var socket1 = client(srv, { multiplex: false });
1102        var socket2 = client(srv, { multiplex: false });
1103
1104        socket2.on('a', function(){
1105          done(new Error('not'));
1106        });
1107        socket1.on('a', function(){
1108          --total || done();
1109        });
1110        socket2.on('b', function(){
1111          --total || done();
1112        });
1113
1114        socket1.emit('join', 'woot');
1115        socket1.emit('join', 'test');
1116        socket2.emit('join', 'third', function(){
1117          socket2.emit('emit');
1118        });
1119
1120        sio.on('connection', function(socket){
1121          socket.on('join', function(room, fn){
1122            socket.join(room, fn);
1123          });
1124
1125          socket.on('emit', function(room){
1126            sio.in('woot').in('test').emit('a');
1127            sio.in('third').emit('b');
1128          });
1129        });
1130      });
1131    });
1132
1133    it('broadcasts to rooms', function(done){
1134      var srv = http();
1135      var sio = io(srv);
1136      var total = 2;
1137
1138      srv.listen(function(){
1139        var socket1 = client(srv, { multiplex: false });
1140        var socket2 = client(srv, { multiplex: false });
1141        var socket3 = client(srv, { multiplex: false });
1142
1143        socket1.emit('join', 'woot');
1144        socket2.emit('join', 'test');
1145        socket3.emit('join', 'test', function(){
1146          socket3.emit('broadcast');
1147        });
1148
1149        socket1.on('a', function(){
1150          done(new Error('not'));
1151        });
1152        socket2.on('a', function(){
1153          --total || done();
1154        });
1155        socket3.on('a', function(){
1156          done(new Error('not'));
1157        });
1158        socket3.on('b', function(){
1159          --total || done();
1160        });
1161
1162        sio.on('connection', function(socket){
1163          socket.on('join', function(room, fn){
1164            socket.join(room, fn);
1165          });
1166
1167          socket.on('broadcast', function(){
1168            socket.broadcast.to('test').emit('a');
1169            socket.emit('b');
1170          });
1171        });
1172      });
1173    });
1174
1175    it('broadcasts binary data to rooms', function(done){
1176      var srv = http();
1177      var sio = io(srv);
1178      var total = 2;
1179
1180      srv.listen(function(){
1181        var socket1 = client(srv, { multiplex: false });
1182        var socket2 = client(srv, { multiplex: false });
1183        var socket3 = client(srv, { multiplex: false });
1184
1185        socket1.emit('join', 'woot');
1186        socket2.emit('join', 'test');
1187        socket3.emit('join', 'test', function(){
1188          socket3.emit('broadcast');
1189        });
1190
1191        socket1.on('bin', function(data){
1192          throw new Error('got bin in socket1');
1193        });
1194        socket2.on('bin', function(data){
1195          expect(Buffer.isBuffer(data)).to.be(true);
1196          --total || done();
1197        });
1198        socket2.on('bin2', function(data) {
1199          throw new Error('socket2 got bin2');
1200        });
1201        socket3.on('bin', function(data) {
1202          throw new Error('socket3 got bin');
1203        });
1204        socket3.on('bin2', function(data) {
1205          expect(Buffer.isBuffer(data)).to.be(true);
1206          --total || done();
1207        });
1208
1209        sio.on('connection', function(socket){
1210          socket.on('join', function(room, fn){
1211            socket.join(room, fn);
1212          });
1213          socket.on('broadcast', function(){
1214            socket.broadcast.to('test').emit('bin', new Buffer(5));
1215            socket.emit('bin2', new Buffer(5));
1216          });
1217        });
1218      });
1219    });
1220
1221
1222    it('keeps track of rooms', function(done){
1223      var srv = http();
1224      var sio = io(srv);
1225
1226      srv.listen(function(){
1227        var socket = client(srv);
1228        sio.on('connection', function(s){
1229          s.join('a', function(){
1230            expect(s.rooms).to.eql([s.id, 'a']);
1231            s.join('b', function(){
1232              expect(s.rooms).to.eql([s.id, 'a', 'b']);
1233              s.leave('b', function(){
1234                expect(s.rooms).to.eql([s.id, 'a']);
1235                done();
1236              });
1237            });
1238          });
1239        });
1240      });
1241    });
1242  });
1243
1244  describe('middleware', function(done){
1245    var Socket = require('../lib/socket');
1246
1247    it('should call functions', function(done){
1248      var srv = http();
1249      var sio = io(srv);
1250      var run = 0;
1251      sio.use(function(socket, next){
1252        expect(socket).to.be.a(Socket);
1253        run++;
1254        next();
1255      });
1256      sio.use(function(socket, next){
1257        expect(socket).to.be.a(Socket);
1258        run++;
1259        next();
1260      });
1261      srv.listen(function(){
1262        var socket = client(srv);
1263        socket.on('connect', function(){
1264          expect(run).to.be(2);
1265          done();
1266        });
1267      });
1268    });
1269
1270    it('should pass errors', function(done){
1271      var srv = http();
1272      var sio = io(srv);
1273      var run = 0;
1274      sio.use(function(socket, next){
1275        next(new Error('Authentication error'));
1276      });
1277      sio.use(function(socket, next){
1278        done(new Error('nope'));
1279      });
1280      srv.listen(function(){
1281        var socket = client(srv);
1282        socket.on('connect', function(){
1283          done(new Error('nope'));
1284        });
1285        socket.on('error', function(err){
1286          expect(err).to.be('Authentication error');
1287          done();
1288        });
1289      });
1290    });
1291
1292    it('should pass `data` of error object', function(done){
1293      var srv = http();
1294      var sio = io(srv);
1295      var run = 0;
1296      sio.use(function(socket, next){
1297        var err = new Error('Authentication error');
1298        err.data = { a: 'b', c: 3 };
1299        next(err);
1300      });
1301      srv.listen(function(){
1302        var socket = client(srv);
1303        socket.on('connect', function(){
1304          done(new Error('nope'));
1305        });
1306        socket.on('error', function(err){
1307          expect(err).to.eql({ a: 'b', c: 3 });
1308          done();
1309        });
1310      });
1311    });
1312
1313    it('should only call connection after fns', function(done){
1314      var srv = http();
1315      var sio = io(srv);
1316      sio.use(function(socket, next){
1317        socket.name = 'guillermo';
1318        next();
1319      });
1320      srv.listen(function(){
1321        var socket = client(srv);
1322        sio.on('connection', function(socket){
1323          expect(socket.name).to.be('guillermo');
1324          done();
1325        });
1326      });
1327    });
1328
1329    it('should be ignored if socket gets closed', function(done){
1330      var srv = http();
1331      var sio = io(srv);
1332      var socket;
1333      sio.use(function(s, next){
1334        socket.io.engine.on('open', function(){
1335          socket.io.engine.close();
1336          s.client.conn.on('close', function(){
1337            process.nextTick(next);
1338            setTimeout(function(){
1339              done();
1340            }, 50);
1341          });
1342        });
1343      });
1344      srv.listen(function(){
1345        socket = client(srv);
1346        sio.on('connection', function(socket){
1347          done(new Error('should not fire'));
1348        });
1349      });
1350    });
1351
1352    it('should call functions in expected order', function(done){
1353      var srv = http();
1354      var sio = io(srv);
1355      var result = [];
1356
1357      sio.use(function(socket, next) {
1358        result.push(1);
1359        setTimeout(next, 50);
1360      });
1361      sio.use(function(socket, next) {
1362        result.push(2);
1363        setTimeout(next, 50);
1364      });
1365      sio.of('/chat').use(function(socket, next) {
1366        result.push(3);
1367        setTimeout(next, 50);
1368      });
1369      sio.of('/chat').use(function(socket, next) {
1370        result.push(4);
1371        setTimeout(next, 50);
1372      });
1373
1374      srv.listen(function() {
1375        var chat = client(srv, '/chat');
1376        chat.on('connect', function() {
1377          expect(result).to.eql([1, 2, 3, 4]);
1378          done();
1379        });
1380      });
1381    });
1382  });
1383});