PageRenderTime 69ms CodeModel.GetById 3ms app.highlight 58ms RepoModel.GetById 1ms app.codeStats 1ms

/test/socket.io.js

https://github.com/eiriklv/socket.io
JavaScript | 1166 lines | 1049 code | 112 blank | 5 comment | 34 complexity | c04d56cabb0b5804558ef02b054478b0 MD5 | raw file
   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('ETag', 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('namespaces', function(){
 265    var Socket = require('../lib/socket');
 266    var Namespace = require('../lib/namespace');
 267
 268    describe('default', function(){
 269      it('should be accessible through .sockets', function(){
 270        var sio = io();
 271        expect(sio.sockets).to.be.a(Namespace);
 272      });
 273
 274      it('should be aliased', function(){
 275        var sio = io();
 276        expect(sio.use).to.be.a('function');
 277        expect(sio.to).to.be.a('function');
 278        expect(sio['in']).to.be.a('function');
 279        expect(sio.emit).to.be.a('function');
 280        expect(sio.send).to.be.a('function');
 281        expect(sio.write).to.be.a('function');
 282      });
 283
 284      it('should automatically connect', function(done){
 285        var srv = http();
 286        var sio = io(srv);
 287        srv.listen(function(){
 288          var socket = client(srv);
 289          socket.on('connect', function(){
 290            done();
 291          });
 292        });
 293      });
 294
 295      it('should fire a `connection` event', function(done){
 296        var srv = http();
 297        var sio = io(srv);
 298        srv.listen(function(){
 299          var socket = client(srv);
 300          sio.on('connection', function(socket){
 301            expect(socket).to.be.a(Socket);
 302            done();
 303          });
 304        });
 305      });
 306
 307      it('should fire a `connect` event', function(done){
 308        var srv = http();
 309        var sio = io(srv);
 310        srv.listen(function(){
 311          var socket = client(srv);
 312          sio.on('connect', function(socket){
 313            expect(socket).to.be.a(Socket);
 314            done();
 315          });
 316        });
 317      });
 318
 319      it('should work with many sockets', function(done){
 320        var srv = http();
 321        var sio = io(srv);
 322        srv.listen(function(){
 323          var chat = client(srv, '/chat');
 324          var news = client(srv, '/news');
 325          var total = 2;
 326          chat.on('connect', function(){
 327            --total || done();
 328          });
 329          news.on('connect', function(){
 330            --total || done();
 331          });
 332        });
 333      });
 334
 335      it('should work with `of` and many sockets', function(done){
 336        var srv = http();
 337        var sio = io(srv);
 338        srv.listen(function(){
 339          var chat = client(srv, '/chat');
 340          var news = client(srv, '/news');
 341          var total = 2;
 342          sio.of('/news').on('connection', function(socket){
 343            expect(socket).to.be.a(Socket);
 344            --total || done();
 345          });
 346          sio.of('/news').on('connection', function(socket){
 347            expect(socket).to.be.a(Socket);
 348            --total || done();
 349          });
 350        });
 351      });
 352
 353      it('should work with `of` second param', function(done){
 354        var srv = http();
 355        var sio = io(srv);
 356        srv.listen(function(){
 357          var chat = client(srv, '/chat');
 358          var news = client(srv, '/news');
 359          var total = 2;
 360          sio.of('/news', function(socket){
 361            expect(socket).to.be.a(Socket);
 362            --total || done();
 363          });
 364          sio.of('/news', function(socket){
 365            expect(socket).to.be.a(Socket);
 366            --total || done();
 367          });
 368        });
 369      });
 370
 371      it('should disconnect upon transport disconnection', function(done){
 372        var srv = http();
 373        var sio = io(srv);
 374        srv.listen(function(){
 375          var chat = client(srv, '/chat');
 376          var news = client(srv, '/news');
 377          var total = 2;
 378          var totald = 2;
 379          var s;
 380          sio.of('/news', function(socket){
 381            socket.on('disconnect', function(reason){
 382              --totald || done();
 383            });
 384            --total || close();
 385          });
 386          sio.of('/chat', function(socket){
 387            s = socket;
 388            socket.on('disconnect', function(reason){
 389              --totald || done();
 390            });
 391            --total || close();
 392          });
 393          function close(){
 394            s.disconnect(true);
 395          }
 396        });
 397      });
 398    });
 399  });
 400
 401  describe('socket', function(){
 402    it('should receive events', function(done){
 403      var srv = http();
 404      var sio = io(srv);
 405      srv.listen(function(){
 406        var socket = client(srv);
 407        sio.on('connection', function(s){
 408          s.on('random', function(a, b, c){
 409            expect(a).to.be(1);
 410            expect(b).to.be('2');
 411            expect(c).to.eql([3]);
 412            done();
 413          });
 414          socket.emit('random', 1, '2', [3]);
 415        });
 416      });
 417    });
 418
 419    it('should receive message events through `send`', function(done){
 420      var srv = http();
 421      var sio = io(srv);
 422      srv.listen(function(){
 423        var socket = client(srv);
 424        sio.on('connection', function(s){
 425          s.on('message', function(a){
 426            expect(a).to.be(1337);
 427            done();
 428          });
 429          socket.send(1337);
 430        });
 431      });
 432    });
 433
 434    it('should emit events', function(done){
 435      var srv = http();
 436      var sio = io(srv);
 437      srv.listen(function(){
 438        var socket = client(srv);
 439        socket.on('woot', function(a){
 440          expect(a).to.be('tobi');
 441          done();
 442        });
 443        sio.on('connection', function(s){
 444          s.emit('woot', 'tobi');
 445        });
 446      });
 447    });
 448
 449    it('should emit events with binary data', function(done){
 450      var srv = http();
 451      var sio = io(srv);
 452      srv.listen(function(){
 453        var socket = client(srv);
 454        var imageData;
 455        socket.on('doge', function(a){
 456          expect(Buffer.isBuffer(a)).to.be(true);
 457          expect(imageData.length).to.equal(a.length);
 458          expect(imageData[0]).to.equal(a[0]);
 459          expect(imageData[imageData.length - 1]).to.equal(a[a.length - 1]);
 460          done();
 461        });
 462        sio.on('connection', function(s){
 463          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 464            if (err) return done(err);
 465            imageData = data;
 466            s.emit('doge', data);
 467          });
 468        });
 469      });
 470    });
 471
 472    it('should emit events with several types of data (including binary)', function(done){
 473      var srv = http();
 474      var sio = io(srv);
 475      srv.listen(function(){
 476        var socket = client(srv);
 477        socket.on('multiple', function(a, b, c, d, e, f){
 478          expect(a).to.be(1);
 479          expect(Buffer.isBuffer(b)).to.be(true);
 480          expect(c).to.be('3');
 481          expect(d).to.eql([4]);
 482          expect(Buffer.isBuffer(e)).to.be(true);
 483          expect(Buffer.isBuffer(f[0])).to.be(true);
 484          expect(f[1]).to.be('swag');
 485          expect(Buffer.isBuffer(f[2])).to.be(true);
 486          done();
 487        });
 488        sio.on('connection', function(s){
 489          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 490            if (err) return done(err);
 491            var buf = new Buffer('asdfasdf', 'utf8');
 492            s.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
 493          });
 494        });
 495      });
 496    });
 497
 498    it('should receive events with binary data', function(done){
 499      var srv = http();
 500      var sio = io(srv);
 501      srv.listen(function(){
 502        var socket = client(srv);
 503        sio.on('connection', function(s){
 504          s.on('buff', function(a){
 505            expect(Buffer.isBuffer(a)).to.be(true);
 506            done();
 507          });
 508          var buf = new Buffer('abcdefg', 'utf8');
 509          socket.emit('buff', buf);
 510        });
 511      });
 512    });
 513
 514    it('should receive events with several types of data (including binary)', function(done){
 515      var srv = http();
 516      var sio = io(srv);
 517      srv.listen(function(){
 518        var socket = client(srv);
 519        sio.on('connection', function(s){
 520          s.on('multiple', function(a, b, c, d, e, f){
 521          expect(a).to.be(1);
 522          expect(Buffer.isBuffer(b)).to.be(true);
 523          expect(c).to.be('3');
 524          expect(d).to.eql([4]);
 525          expect(Buffer.isBuffer(e)).to.be(true);
 526          expect(Buffer.isBuffer(f[0])).to.be(true);
 527          expect(f[1]).to.be('swag');
 528          expect(Buffer.isBuffer(f[2])).to.be(true);
 529          done();
 530          });
 531          fs.readFile(join(__dirname, 'support', 'doge.jpg'), function(err, data){
 532            if (err) return done(err);
 533            var buf = new Buffer('asdfasdf', 'utf8');
 534            socket.emit('multiple', 1, data, '3', [4], buf, [data, 'swag', buf]);
 535          });
 536        });
 537      });
 538    });
 539
 540    it('should emit message events through `send`', function(done){
 541      var srv = http();
 542      var sio = io(srv);
 543      srv.listen(function(){
 544        var socket = client(srv);
 545        socket.on('message', function(a){
 546          expect(a).to.be('a');
 547          done();
 548        });
 549        sio.on('connection', function(s){
 550          s.send('a');
 551        });
 552      });
 553    });
 554
 555    it('should receive event with callbacks', function(done){
 556      var srv = http();
 557      var sio = io(srv);
 558      srv.listen(function(){
 559        var socket = client(srv);
 560        sio.on('connection', function(s){
 561          s.on('woot', function(fn){
 562            fn(1, 2);
 563          });
 564          socket.emit('woot', function(a, b){
 565            expect(a).to.be(1);
 566            expect(b).to.be(2);
 567            done();
 568          });
 569        });
 570      });
 571    });
 572
 573    it('should emit events with callbacks', function(done){
 574      var srv = http();
 575      var sio = io(srv);
 576      srv.listen(function(){
 577        var socket = client(srv);
 578        sio.on('connection', function(s){
 579          socket.on('hi', function(fn){
 580            fn();
 581          });
 582          s.emit('hi', function(){
 583            done();
 584          });
 585        });
 586      });
 587    });
 588
 589    it('should receive events with args and callback', function(done){
 590      var srv = http();
 591      var sio = io(srv);
 592      srv.listen(function(){
 593        var socket = client(srv);
 594        sio.on('connection', function(s){
 595          s.on('woot', function(a, b, fn){
 596            expect(a).to.be(1);
 597            expect(b).to.be(2);
 598            fn();
 599          });
 600          socket.emit('woot', 1, 2, function(){
 601            done();
 602          });
 603        });
 604      });
 605    });
 606
 607    it('should emit events with args and callback', function(done){
 608      var srv = http();
 609      var sio = io(srv);
 610      srv.listen(function(){
 611        var socket = client(srv);
 612        sio.on('connection', function(s){
 613          socket.on('hi', function(a, b, fn){
 614            expect(a).to.be(1);
 615            expect(b).to.be(2);
 616            fn();
 617          });
 618          s.emit('hi', 1, 2, function(){
 619            done();
 620          });
 621        });
 622      });
 623    });
 624
 625    it('should receive events with binary args and callbacks', function(done) {
 626      var srv = http();
 627      var sio = io(srv);
 628      srv.listen(function(){
 629        var socket = client(srv);
 630        sio.on('connection', function(s){
 631          s.on('woot', function(buf, fn){
 632            expect(Buffer.isBuffer(buf)).to.be(true);
 633            fn(1, 2);
 634          });
 635          socket.emit('woot', new Buffer(3), function(a, b){
 636            expect(a).to.be(1);
 637            expect(b).to.be(2);
 638            done();
 639          });
 640        });
 641      });
 642    });
 643
 644    it('should emit events with binary args and callback', function(done){
 645      var srv = http();
 646      var sio = io(srv);
 647      srv.listen(function(){
 648        var socket = client(srv);
 649        sio.on('connection', function(s){
 650          socket.on('hi', function(a, fn){
 651            expect(Buffer.isBuffer(a)).to.be(true);
 652            fn();
 653          });
 654          s.emit('hi', new Buffer(4), function(){
 655            done();
 656          });
 657        });
 658      });
 659    });
 660
 661    it('should emit events and receive binary data in a callback', function(done) {
 662      var srv = http();
 663      var sio = io(srv);
 664      srv.listen(function(){
 665        var socket = client(srv);
 666        sio.on('connection', function(s){
 667          socket.on('hi', function(fn){
 668            fn(new Buffer(1));
 669          });
 670          s.emit('hi', function(a){
 671            expect(Buffer.isBuffer(a)).to.be(true);
 672            done();
 673          });
 674        });
 675      });
 676    });
 677
 678    it('should receive events and pass binary data in a callback', function(done) {
 679      var srv = http();
 680      var sio = io(srv);
 681      srv.listen(function(){
 682        var socket = client(srv);
 683        sio.on('connection', function(s){
 684          s.on('woot', function(fn){
 685            fn(new Buffer(2));
 686          });
 687          socket.emit('woot', function(a){
 688            expect(Buffer.isBuffer(a)).to.be(true);
 689            done();
 690          });
 691        });
 692      });
 693    });
 694
 695    it('should have access to the client', 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          expect(s.client).to.be.an('object');
 702          done();
 703        });
 704      });
 705    });
 706
 707    it('should have access to the connection', function(done){
 708      var srv = http();
 709      var sio = io(srv);
 710      srv.listen(function(){
 711        var socket = client(srv);
 712        sio.on('connection', function(s){
 713          expect(s.client.conn).to.be.an('object');
 714          expect(s.conn).to.be.an('object');
 715          done();
 716        });
 717      });
 718    });
 719
 720    it('should have access to the request', function(done){
 721      var srv = http();
 722      var sio = io(srv);
 723      srv.listen(function(){
 724        var socket = client(srv);
 725        sio.on('connection', function(s){
 726          expect(s.client.request.headers).to.be.an('object');
 727          expect(s.request.headers).to.be.an('object');
 728          done();
 729        });
 730      });
 731    });
 732
 733    it('should see query parameters in the request', function(done) {
 734      var srv = http();
 735      var sio = io(srv);
 736      srv.listen(function() {
 737        var addr = srv.listen().address();
 738        var url = 'ws://' + addr.address + ':' + addr.port + '?key1=1&key2=2';
 739        var socket = ioc(url);
 740        sio.on('connection', function(s) {
 741          var parsed = require('url').parse(s.request.url);
 742          var query = require('querystring').parse(parsed.query);
 743          expect(query.key1).to.be('1');
 744          expect(query.key2).to.be('2');
 745          done();
 746        });
 747      });
 748    });
 749  });
 750
 751  describe('messaging many', function(){
 752    it('emits to a namespace', function(done){
 753      var srv = http();
 754      var sio = io(srv);
 755      var total = 2;
 756
 757      srv.listen(function(){
 758        var socket1 = client(srv, { multiplex: false });
 759        var socket2 = client(srv, { multiplex: false });
 760        var socket3 = client(srv, '/test');
 761        socket1.on('a', function(a){
 762          expect(a).to.be('b');
 763          --total || done();
 764        });
 765        socket2.on('a', function(a){
 766          expect(a).to.be('b');
 767          --total || done();
 768        });
 769        socket3.on('a', function(){ done(new Error('not')); });
 770
 771        var sockets = 3;
 772        sio.on('connection', function(socket){
 773          --sockets || emit();
 774        });
 775        sio.of('/test', function(socket){
 776          --sockets || emit();
 777        });
 778
 779        function emit(){
 780          sio.emit('a', 'b');
 781        }
 782      });
 783    });
 784
 785    it('emits binary data to a namespace', function(done){
 786      var srv = http();
 787      var sio = io(srv);
 788      var total = 2;
 789
 790      srv.listen(function(){
 791        var socket1 = client(srv, { multiplex: false });
 792        var socket2 = client(srv, { multiplex: false });
 793        var socket3 = client(srv, '/test');
 794        socket1.on('bin', function(a){
 795          expect(Buffer.isBuffer(a)).to.be(true);
 796          --total || done();
 797        });
 798        socket2.on('bin', function(a){
 799          expect(Buffer.isBuffer(a)).to.be(true);
 800          --total || done();
 801        });
 802        socket3.on('bin', function(){ done(new Error('not')); });
 803
 804        var sockets = 3;
 805        sio.on('connection', function(socket){
 806          --sockets || emit();
 807        });
 808        sio.of('/test', function(socket){
 809          --sockets || emit();
 810        });
 811
 812        function emit(){
 813          sio.emit('bin', new Buffer(10));
 814        }
 815      });
 816    });
 817
 818    it('emits to the rest', function(done){
 819      var srv = http();
 820      var sio = io(srv);
 821      var total = 2;
 822
 823      srv.listen(function(){
 824        var socket1 = client(srv, { multiplex: false });
 825        var socket2 = client(srv, { multiplex: false });
 826        var socket3 = client(srv, '/test');
 827        socket1.on('a', function(a){
 828          expect(a).to.be('b');
 829          socket1.emit('finish');
 830        });
 831        socket2.emit('broadcast');
 832        socket2.on('a', function(){ done(new Error('done')); });
 833        socket3.on('a', function(){ done(new Error('not')); });
 834
 835        var sockets = 2;
 836        sio.on('connection', function(socket){
 837          socket.on('broadcast', function(){
 838            socket.broadcast.emit('a', 'b');
 839          });
 840          socket.on('finish', function(){
 841            done();
 842          });
 843        });
 844      });
 845    });
 846
 847    it('emits to rooms', function(done){
 848      var srv = http();
 849      var sio = io(srv);
 850      var total = 2;
 851
 852      srv.listen(function(){
 853        var socket1 = client(srv, { multiplex: false });
 854        var socket2 = client(srv, { multiplex: false });
 855
 856        socket2.on('a', function(){
 857          done(new Error('not'));
 858        });
 859        socket1.on('a', function(){
 860          done();
 861        });
 862        socket1.emit('join', 'woot', function(){
 863          socket1.emit('emit', 'woot');
 864        });
 865
 866        sio.on('connection', function(socket){
 867          socket.on('join', function(room, fn){
 868            socket.join(room, fn);
 869          });
 870
 871          socket.on('emit', function(room){
 872            sio.in(room).emit('a');
 873          });
 874        });
 875      });
 876    });
 877
 878    it('emits to rooms avoiding dupes', function(done){
 879      var srv = http();
 880      var sio = io(srv);
 881      var total = 2;
 882
 883      srv.listen(function(){
 884        var socket1 = client(srv, { multiplex: false });
 885        var socket2 = client(srv, { multiplex: false });
 886
 887        socket2.on('a', function(){
 888          done(new Error('not'));
 889        });
 890        socket1.on('a', function(){
 891          --total || done();
 892        });
 893        socket2.on('b', function(){
 894          --total || done();
 895        });
 896
 897        socket1.emit('join', 'woot');
 898        socket1.emit('join', 'test');
 899        socket2.emit('join', 'third', function(){
 900          socket2.emit('emit');
 901        });
 902
 903        sio.on('connection', function(socket){
 904          socket.on('join', function(room, fn){
 905            socket.join(room, fn);
 906          });
 907
 908          socket.on('emit', function(room){
 909            sio.in('woot').in('test').emit('a');
 910            sio.in('third').emit('b');
 911          });
 912        });
 913      });
 914    });
 915
 916    it('broadcasts to rooms', function(done){
 917      var srv = http();
 918      var sio = io(srv);
 919      var total = 2;
 920
 921      srv.listen(function(){
 922        var socket1 = client(srv, { multiplex: false });
 923        var socket2 = client(srv, { multiplex: false });
 924        var socket3 = client(srv, { multiplex: false });
 925
 926        socket1.emit('join', 'woot');
 927        socket2.emit('join', 'test');
 928        socket3.emit('join', 'test', function(){
 929          socket3.emit('broadcast');
 930        });
 931
 932        socket1.on('a', function(){
 933          done(new Error('not'));
 934        });
 935        socket2.on('a', function(){
 936          --total || done();
 937        });
 938        socket3.on('a', function(){
 939          done(new Error('not'));
 940        });
 941        socket3.on('b', function(){
 942          --total || done();
 943        });
 944
 945        sio.on('connection', function(socket){
 946          socket.on('join', function(room, fn){
 947            socket.join(room, fn);
 948          });
 949
 950          socket.on('broadcast', function(){
 951            socket.broadcast.to('test').emit('a');
 952            socket.emit('b');
 953          });
 954        });
 955      });
 956    });
 957
 958    it('broadcasts binary data to rooms', function(done){
 959      var srv = http();
 960      var sio = io(srv);
 961      var total = 2;
 962
 963      srv.listen(function(){
 964        var socket1 = client(srv, { multiplex: false });
 965        var socket2 = client(srv, { multiplex: false });
 966        var socket3 = client(srv, { multiplex: false });
 967
 968        socket1.emit('join', 'woot');
 969        socket2.emit('join', 'test');
 970        socket3.emit('join', 'test', function(){
 971          socket3.emit('broadcast');
 972        });
 973
 974        socket1.on('bin', function(data){
 975          throw new Error('got bin in socket1');
 976        });
 977        socket2.on('bin', function(data){
 978          expect(Buffer.isBuffer(data)).to.be(true);
 979          --total || done();
 980        });
 981        socket2.on('bin2', function(data) {
 982          throw new Error('socket2 got bin2');
 983        });
 984        socket3.on('bin', function(data) {
 985          throw new Error('socket3 got bin');
 986        });
 987        socket3.on('bin2', function(data) {
 988          expect(Buffer.isBuffer(data)).to.be(true);
 989          --total || done();
 990        });
 991
 992        sio.on('connection', function(socket){
 993          socket.on('join', function(room, fn){
 994            socket.join(room, fn);
 995          });
 996          socket.on('broadcast', function(){
 997            socket.broadcast.to('test').emit('bin', new Buffer(5));
 998            socket.emit('bin2', new Buffer(5));
 999          });
1000        });
1001      });
1002    });
1003
1004
1005    it('keeps track of rooms', function(done){
1006      var srv = http();
1007      var sio = io(srv);
1008
1009      srv.listen(function(){
1010        var socket = client(srv);
1011        sio.on('connection', function(s){
1012          s.join('a', function(){
1013            expect(s.rooms).to.eql([s.id, 'a']);
1014            s.join('b', function(){
1015              expect(s.rooms).to.eql([s.id, 'a', 'b']);
1016              s.leave('b', function(){
1017                expect(s.rooms).to.eql([s.id, 'a']);
1018                done();
1019              });
1020            });
1021          });
1022        });
1023      });
1024    });
1025  });
1026
1027  describe('middleware', function(done){
1028    var Socket = require('../lib/socket');
1029
1030    it('should call functions', function(done){
1031      var srv = http();
1032      var sio = io(srv);
1033      var run = 0;
1034      sio.use(function(socket, next){
1035        expect(socket).to.be.a(Socket);
1036        run++;
1037        next();
1038      });
1039      sio.use(function(socket, next){
1040        expect(socket).to.be.a(Socket);
1041        run++;
1042        next();
1043      });
1044      srv.listen(function(){
1045        var socket = client(srv);
1046        socket.on('connect', function(){
1047          expect(run).to.be(2);
1048          done();
1049        });
1050      });
1051    });
1052
1053    it('should pass errors', function(done){
1054      var srv = http();
1055      var sio = io(srv);
1056      var run = 0;
1057      sio.use(function(socket, next){
1058        next(new Error('Authentication error'));
1059      });
1060      sio.use(function(socket, next){
1061        done(new Error('nope'));
1062      });
1063      srv.listen(function(){
1064        var socket = client(srv);
1065        socket.on('connect', function(){
1066          done(new Error('nope'));
1067        });
1068        socket.on('error', function(err){
1069          expect(err).to.be('Authentication error');
1070          done();
1071        });
1072      });
1073    });
1074
1075    it('should pass `data` of error object', function(done){
1076      var srv = http();
1077      var sio = io(srv);
1078      var run = 0;
1079      sio.use(function(socket, next){
1080        var err = new Error('Authentication error');
1081        err.data = { a: 'b', c: 3 };
1082        next(err);
1083      });
1084      srv.listen(function(){
1085        var socket = client(srv);
1086        socket.on('connect', function(){
1087          done(new Error('nope'));
1088        });
1089        socket.on('error', function(err){
1090          expect(err).to.eql({ a: 'b', c: 3 });
1091          done();
1092        });
1093      });
1094    });
1095
1096    it('should only call connection after fns', function(done){
1097      var srv = http();
1098      var sio = io(srv);
1099      sio.use(function(socket, next){
1100        socket.name = 'guillermo';
1101        next();
1102      });
1103      srv.listen(function(){
1104        var socket = client(srv);
1105        sio.on('connection', function(socket){
1106          expect(socket.name).to.be('guillermo');
1107          done();
1108        });
1109      });
1110    });
1111
1112    it('should be ignored if socket gets closed', function(done){
1113      var srv = http();
1114      var sio = io(srv);
1115      var socket;
1116      sio.use(function(s, next){
1117        socket.io.engine.on('open', function(){
1118          socket.io.engine.close();
1119          s.client.conn.on('close', function(){
1120            process.nextTick(next);
1121            setTimeout(function(){
1122              done();
1123            }, 50);
1124          });
1125        });
1126      });
1127      srv.listen(function(){
1128        socket = client(srv);
1129        sio.on('connection', function(socket){
1130          done(new Error('should not fire'));
1131        });
1132      });
1133    });
1134
1135    it('should call functions in expected order', function(done){
1136      var srv = http();
1137      var sio = io(srv);
1138      var result = [];
1139
1140      sio.use(function(socket, next) {
1141        result.push(1);
1142        setTimeout(next, 50);
1143      });
1144      sio.use(function(socket, next) {
1145        result.push(2);
1146        setTimeout(next, 50);
1147      });
1148      sio.of('/chat').use(function(socket, next) {
1149        result.push(3);
1150        setTimeout(next, 50);
1151      });
1152      sio.of('/chat').use(function(socket, next) {
1153        result.push(4);
1154        setTimeout(next, 50);
1155      });
1156
1157      srv.listen(function() {
1158        var chat = client(srv, '/chat');
1159        chat.on('connect', function() {
1160          expect(result).to.eql([1, 2, 3, 4]);
1161          done();
1162        });
1163      });
1164    });
1165  });
1166});