PageRenderTime 106ms CodeModel.GetById 18ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 0ms

/node_modules/now/node_modules/socket.io/test/transports.websocket.test.js

https://github.com/tkpage/oasys
JavaScript | 1771 lines | 1512 code | 248 blank | 11 comment | 147 complexity | 107269a504d77d2f4d5ad5945a625277 MD5 | raw file
   1
   2/*!
   3 * socket.io-node
   4 * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
   5 * MIT Licensed
   6 */
   7
   8/**
   9 * Test dependencies.
  10 */
  11
  12var sio = require('socket.io')
  13  , should = require('./common')
  14  , parser = sio.parser
  15  , ports = 15800;
  16
  17/**
  18 * Tests.
  19 */
  20
  21module.exports = {
  22
  23  'test that not responding to a heartbeat drops client': function (done) {
  24    var cl = client(++ports)
  25      , io = create(cl)
  26      , messages = 0
  27      , ws;
  28
  29    io.configure(function () {
  30      io.set('heartbeat interval', .05);
  31      io.set('heartbeat timeout', .05);
  32      io.set('close timeout', 0);
  33    });
  34
  35    io.sockets.on('connection', function (socket) {
  36      socket.on('disconnect', function (reason) {
  37        beat.should.be.true;
  38        reason.should.eql('heartbeat timeout');
  39
  40        cl.end();
  41        ws.finishClose();
  42        io.server.close();
  43        done();
  44      });
  45    });
  46
  47    cl.handshake(function (sid) {
  48      ws = websocket(cl, sid);
  49      ws.on('message', function (packet) {
  50        if (++messages == 1) {
  51          packet.type.should.eql('connect');
  52        } else {
  53          packet.type.should.eql('heartbeat');
  54          beat = true;
  55        }
  56      });
  57    });
  58  },
  59
  60  'test that responding to a heartbeat maintains session': function (done) {
  61    var cl = client(++ports)
  62      , io = create(cl)
  63      , messages = 0
  64      , heartbeats = 0
  65      , ws;
  66
  67    io.configure(function () {
  68      io.set('heartbeat interval', .05);
  69      io.set('heartbeat timeout', .05);
  70      io.set('close timeout', 0);
  71    });
  72
  73    io.sockets.on('connection', function (socket) {
  74      socket.on('disconnect', function (reason) {
  75        heartbeats.should.eql(2);
  76        reason.should.eql('heartbeat timeout');
  77
  78        cl.end();
  79        ws.finishClose();
  80        io.server.close();
  81        done();
  82      });
  83    });
  84
  85    cl.handshake(function (sid) {
  86      ws = websocket(cl, sid);
  87      ws.on('message', function (packet) {
  88        if (++messages == 1) {
  89          packet.type.should.eql('connect');
  90        } else {
  91          packet.type.should.eql('heartbeat');
  92          heartbeats++;
  93
  94          if (heartbeats == 1) {
  95            ws.packet({ type: 'heartbeat' });
  96          }
  97        }
  98      });
  99    });
 100  },
 101
 102  'test sending undeliverable volatile messages': function (done) {
 103    var cl = client(++ports)
 104      , io = create(cl)
 105      , messages = 0
 106      , messaged = false
 107      , s;
 108
 109    io.configure(function () {
 110      io.set('close timeout', .05);
 111    });
 112
 113    io.sockets.on('connection', function (socket) {
 114      s = socket;
 115
 116      socket.on('disconnect', function () {
 117        messaged.should.be.false;
 118        cl.end();
 119        io.server.close();
 120        done();
 121      });
 122    });
 123
 124    cl.handshake(function (sid) {
 125      var ws = websocket(cl, sid);
 126      ws.on('message', function (msg) {
 127        msg.type.should.eql('connect');
 128        ws.finishClose();
 129
 130        setTimeout(function () {
 131          s.volatile.send('ah wha wha');
 132
 133          ws = websocket(cl, sid);
 134          ws.on('message', function () {
 135            messaged = true;
 136          });
 137
 138          setTimeout(function () {
 139            ws.finishClose();
 140          }, 10);
 141        }, 10);
 142      });
 143    });
 144  },
 145
 146  'test sending undeliverable volatile json': function (done) {
 147    var cl = client(++ports)
 148      , io = create(cl)
 149      , messaged = false
 150      , s;
 151
 152    io.configure(function () {
 153      io.set('close timeout', .05);
 154    });
 155
 156    io.sockets.on('connection', function (socket) {
 157      s = socket;
 158
 159      socket.on('disconnect', function () {
 160        messaged.should.be.false;
 161        cl.end();
 162        io.server.close();
 163        done();
 164      });
 165    });
 166
 167    cl.handshake(function (sid) {
 168      var ws = websocket(cl, sid);
 169      ws.on('message', function () {
 170        ws.finishClose();
 171
 172        setTimeout(function () {
 173          s.volatile.json.send({ a: 'b' });
 174
 175          ws = websocket(cl, sid);
 176          ws.on('message', function () {
 177            messaged = true;
 178          });
 179
 180          setTimeout(function () {
 181            ws.finishClose();
 182          }, 10);
 183        }, 10);
 184      });
 185    });
 186  },
 187
 188  'test sending undeliverable volatile events': function (done) {
 189    var cl = client(++ports)
 190      , io = create(cl)
 191      , messaged = false
 192      , s;
 193
 194    io.configure(function () {
 195      io.set('close timeout', .05);
 196    });
 197
 198    io.sockets.on('connection', function (socket) {
 199      s = socket;
 200
 201      socket.on('disconnect', function () {
 202        messaged.should.be.false;
 203        cl.end();
 204        io.server.close();
 205        done();
 206      });
 207    });
 208
 209    cl.handshake(function (sid) {
 210      var ws = websocket(cl, sid);
 211      ws.on('message', function () {
 212        ws.finishClose();
 213
 214        setTimeout(function () {
 215          s.volatile.emit({ a: 'b' });
 216
 217          ws = websocket(cl, sid);
 218          ws.on('message', function () {
 219            messaged = true;
 220          });
 221
 222          setTimeout(function () {
 223            ws.finishClose();
 224          }, 10);
 225        }, 10);
 226      });
 227    });
 228  },
 229
 230  'test sending deliverable volatile messages': function (done) {
 231    var cl = client(++ports)
 232      , io = create(cl)
 233      , messages = 0
 234      , messaged = false;
 235
 236    io.configure(function () {
 237      io.set('close timeout', .05);
 238    });
 239
 240    io.sockets.on('connection', function (socket) {
 241      socket.volatile.send('tobi');
 242
 243      socket.on('disconnect', function () {
 244        messaged.should.be.true;
 245        cl.end();
 246        io.server.close();
 247        done();
 248      });
 249    });
 250
 251    cl.handshake(function (sid) {
 252      var ws = websocket(cl, sid);
 253      ws.on('message', function (msg) {
 254        if (++messages == 1) {
 255          msg.type.should.eql('connect');
 256        } else {
 257          msg.should.eql({
 258              type: 'message'
 259            , data: 'tobi'
 260            , endpoint: ''
 261          });
 262          messaged = true;
 263          ws.finishClose();
 264        }
 265      });
 266    });
 267  },
 268
 269  'test sending deliverable volatile json': function (done) {
 270    var cl = client(++ports)
 271      , io = create(cl)
 272      , messaged = false;
 273
 274    io.configure(function () {
 275      io.set('close timeout', .05);
 276    });
 277
 278    io.sockets.on('connection', function (socket) {
 279      socket.volatile.json.send([1, 2, 3]);
 280
 281      socket.on('disconnect', function () {
 282        messaged.should.be.true;
 283        cl.end();
 284        io.server.close();
 285        done();
 286      });
 287    });
 288
 289    cl.handshake(function (sid) {
 290      var ws = websocket(cl, sid);
 291      ws.on('message', function (msg) {
 292        if (!ws.connected) {
 293          msg.type.should.eql('connect');
 294          ws.connected = true;
 295        } else {
 296          msg.should.eql({
 297              type: 'json'
 298            , data: [1, 2, 3]
 299            , endpoint: ''
 300          });
 301          messaged = true;
 302          ws.finishClose();
 303        }
 304      });
 305    });
 306  },
 307
 308  'test sending deliverable volatile events': function (done) {
 309    var cl = client(++ports)
 310      , io = create(cl)
 311      , messaged = false;
 312
 313    io.configure(function () {
 314      io.set('close timeout', .05);
 315    });
 316
 317    io.sockets.on('connection', function (socket) {
 318      socket.volatile.emit('tobi');
 319
 320      socket.on('disconnect', function () {
 321        messaged.should.be.true;
 322        cl.end();
 323        io.server.close();
 324        done();
 325      });
 326    });
 327
 328    cl.handshake(function (sid) {
 329      var ws = websocket(cl, sid);
 330      ws.on('message', function (msg) {
 331        if (!ws.connected) {
 332          msg.type.should.eql('connect');
 333          ws.connected = true;
 334        } else {
 335          msg.should.eql({
 336              type: 'event'
 337            , name: 'tobi'
 338            , endpoint: ''
 339            , args: []
 340          });
 341          messaged = true;
 342          ws.finishClose();
 343        }
 344      });
 345    });
 346  },
 347
 348  'test sending to all clients in a namespace': function (done) {
 349    var port = ++ports
 350      , cl1 = client(port)
 351      , cl2 = client(port)
 352      , io = create(cl1)
 353      , messages = 0
 354      , connections = 0
 355      , disconnections = 0;
 356
 357    io.configure(function () {
 358      io.set('close timeout', 0);
 359    });
 360
 361    io.sockets.on('connection', function (socket) {
 362      connections++;
 363
 364      if (connections == 2) {
 365        io.sockets.send('yup');
 366      }
 367
 368      socket.on('disconnect', function () {
 369        disconnections++;
 370
 371        if (disconnections == 2) {
 372          messages.should.eql(2);
 373          cl1.end();
 374          cl2.end();
 375          io.server.close();
 376          done();
 377        }
 378      });
 379    });
 380
 381    cl1.handshake(function (sid) {
 382      var ws1 = websocket(cl1, sid);
 383      ws1.on('message', function (msg) {
 384        if (!ws1.connected) {
 385          msg.type.should.eql('connect');
 386          ws1.connected = true;
 387        } else {
 388          msg.should.eql({
 389              type: 'message'
 390            , data: 'yup'
 391            , endpoint: ''
 392          });
 393
 394          messages++;
 395          ws1.finishClose();
 396        }
 397      });
 398    });
 399
 400    cl2.handshake(function (sid) {
 401      var ws2 = websocket(cl2, sid);
 402      ws2.on('message', function (msg) {
 403        if (!ws2.connected) {
 404          msg.type.should.eql('connect');
 405          ws2.connected = true;
 406        } else {
 407          msg.should.eql({
 408              type: 'message'
 409            , data: 'yup'
 410            , endpoint: ''
 411          });
 412
 413          messages++;
 414          ws2.finishClose();
 415        }
 416      });
 417    });
 418  },
 419
 420  'test sending json to all clients in a namespace': function (done) {
 421    var port = ++ports
 422      , cl1 = client(port)
 423      , cl2 = client(port)
 424      , io = create(cl1)
 425      , messages = 0
 426      , connections = 0
 427      , disconnections = 0;
 428
 429    io.configure(function () {
 430      io.set('close timeout', 0);
 431    });
 432
 433    io.sockets.on('connection', function (socket) {
 434      connections++;
 435
 436      if (connections == 2) {
 437        io.sockets.json.send({ a: 'b' });
 438      }
 439
 440      socket.on('disconnect', function () {
 441        disconnections++;
 442
 443        if (disconnections == 2) {
 444          messages.should.eql(2);
 445          cl1.end();
 446          cl2.end();
 447          io.server.close();
 448          done();
 449        }
 450      });
 451    });
 452
 453    cl1.handshake(function (sid) {
 454      var ws1 = websocket(cl1, sid);
 455      ws1.on('message', function (msg) {
 456        if (!ws1.connected) {
 457          msg.type.should.eql('connect');
 458          ws1.connected = true;
 459        } else {
 460          msg.should.eql({
 461              type: 'json'
 462            , data: { a: 'b' }
 463            , endpoint: ''
 464          });
 465
 466          messages++;
 467          ws1.finishClose();
 468        }
 469      });
 470    });
 471
 472    cl2.handshake(function (sid) {
 473      var ws2 = websocket(cl2, sid);
 474      ws2.on('message', function (msg) {
 475        if (!ws2.connected) {
 476          msg.type.should.eql('connect');
 477          ws2.connected = true;
 478        } else {
 479          msg.should.eql({
 480              type: 'json'
 481            , data: { a: 'b' }
 482            , endpoint: ''
 483          });
 484
 485          messages++;
 486          ws2.finishClose();
 487        }
 488      });
 489    });
 490  },
 491
 492  'test emitting to all clients in a namespace': function (done) {
 493    var port = ++ports
 494      , cl1 = client(port)
 495      , cl2 = client(port)
 496      , io = create(cl1)
 497      , messages = 0
 498      , connections = 0
 499      , disconnections = 0;
 500
 501    io.configure(function () {
 502      io.set('close timeout', 0);
 503    });
 504
 505    io.sockets.on('connection', function (socket) {
 506      connections++;
 507
 508      if (connections == 2) {
 509        io.sockets.emit('tobi', 'rapture');
 510      }
 511
 512      socket.on('disconnect', function () {
 513        disconnections++;
 514
 515        if (disconnections == 2) {
 516          messages.should.eql(2);
 517          cl1.end();
 518          cl2.end();
 519          io.server.close();
 520          done();
 521        }
 522      });
 523    });
 524
 525    cl1.handshake(function (sid) {
 526      var ws1 = websocket(cl1, sid);
 527      ws1.on('message', function (msg) {
 528        if (!ws1.connected) {
 529          msg.type.should.eql('connect');
 530          ws1.connected = true;
 531        } else {
 532          msg.should.eql({
 533              type: 'event'
 534            , name: 'tobi'
 535            , args: ['rapture']
 536            , endpoint: ''
 537          });
 538
 539          messages++;
 540          ws1.finishClose();
 541        }
 542      });
 543    });
 544
 545    cl2.handshake(function (sid) {
 546      var ws2 = websocket(cl2, sid);
 547      ws2.on('message', function (msg) {
 548        if (!ws2.connected) {
 549          msg.type.should.eql('connect');
 550          ws2.connected = true;
 551        } else {
 552          msg.should.eql({
 553              type: 'event'
 554            , name: 'tobi'
 555            , args: ['rapture']
 556            , endpoint: ''
 557          });
 558
 559          messages++;
 560          ws2.finishClose();
 561        }
 562      });
 563    });
 564  },
 565
 566  'test sending to all clients in a room': function (done) {
 567    var port = ++ports
 568      , cl1 = client(port)
 569      , cl2 = client(port)
 570      , cl3 = client(port)
 571      , io = create(cl1)
 572      , messages = 0
 573      , joins = 0
 574      , connections = 0
 575      , disconnections = 0;
 576
 577    io.configure(function () {
 578      io.set('close timeout', 0);
 579    });
 580
 581    io.sockets.on('connection', function (socket) {
 582      connections++;
 583
 584      if (connections != 3) {
 585        socket.join('woot');
 586        joins++;
 587
 588        if (joins == 2) {
 589          setTimeout(function () {
 590            connections.should.eql(3);
 591            io.sockets.in('woot').send('hahaha');
 592          }, 20);
 593        }
 594      }
 595
 596      socket.on('disconnect', function () {
 597        disconnections++;
 598
 599        if (disconnections == 3) {
 600          messages.should.eql(2);
 601          cl1.end();
 602          cl2.end();
 603          cl3.end();
 604          io.server.close();
 605          done();
 606        }
 607      });
 608    });
 609
 610    cl1.handshake(function (sid) {
 611      var ws1 = websocket(cl1, sid);
 612      ws1.on('message', function (msg) {
 613        if (!ws1.connected) {
 614          msg.type.should.eql('connect');
 615          ws1.connected = true;
 616        } else {
 617          msg.should.eql({
 618              type: 'message'
 619            , data: 'hahaha'
 620            , endpoint: ''
 621          });
 622
 623          messages++;
 624        }
 625      });
 626
 627      setTimeout(function () {
 628        ws1.finishClose();
 629      }, 50);
 630    });
 631
 632    cl2.handshake(function (sid) {
 633      var ws2 = websocket(cl2, sid);
 634      ws2.on('message', function (msg) {
 635        if (!ws2.connected) {
 636          msg.type.should.eql('connect');
 637          ws2.connected = true;
 638        } else {
 639          msg.should.eql({
 640              type: 'message'
 641            , data: 'hahaha'
 642            , endpoint: ''
 643          });
 644
 645          messages++;
 646        }
 647      });
 648
 649      setTimeout(function () {
 650        ws2.finishClose();
 651      }, 50);
 652    });
 653
 654    cl3.handshake(function (sid) {
 655      var ws3 = websocket(cl3, sid);
 656      ws3.on('message', function (msg) {
 657        if (!ws3.connected) {
 658          msg.type.should.eql('connect');
 659          ws3.connected = true;
 660        } else {
 661          msg.should.eql({
 662              type: 'message'
 663            , data: 'hahaha'
 664            , endpoint: ''
 665          });
 666
 667          messages++;
 668        }
 669      });
 670
 671      setTimeout(function () {
 672        ws3.finishClose();
 673      }, 50);
 674    });
 675  },
 676
 677  'test sending json to all clients in a room': function (done) {
 678    var port = ++ports
 679      , cl1 = client(port)
 680      , cl2 = client(port)
 681      , cl3 = client(port)
 682      , io = create(cl1)
 683      , messages = 0
 684      , joins = 0
 685      , connections = 0
 686      , disconnections = 0;
 687
 688    io.configure(function () {
 689      io.set('close timeout', 0);
 690    });
 691
 692    io.sockets.on('connection', function (socket) {
 693      connections++;
 694
 695      if (connections != 3) {
 696        socket.join('woot');
 697        joins++;
 698
 699        if (joins == 2) {
 700          setTimeout(function () {
 701            connections.should.eql(3);
 702            io.sockets.in('woot').json.send(123);
 703          }, 20);
 704        }
 705      }
 706
 707      socket.on('disconnect', function () {
 708        disconnections++;
 709
 710        if (disconnections == 3) {
 711          messages.should.eql(2);
 712          cl1.end();
 713          cl2.end();
 714          cl3.end();
 715          io.server.close();
 716          done();
 717        }
 718      });
 719    });
 720
 721    cl1.handshake(function (sid) {
 722      var ws1 = websocket(cl1, sid);
 723      ws1.on('message', function (msg) {
 724        if (!ws1.connected) {
 725          msg.type.should.eql('connect');
 726          ws1.connected = true;
 727        } else {
 728          msg.should.eql({
 729              type: 'json'
 730            , data: 123
 731            , endpoint: ''
 732          });
 733
 734          messages++;
 735        }
 736      });
 737
 738      setTimeout(function () {
 739        ws1.finishClose();
 740      }, 50);
 741    });
 742
 743    cl2.handshake(function (sid) {
 744      var ws2 = websocket(cl2, sid);
 745      ws2.on('message', function (msg) {
 746        if (!ws2.connected) {
 747          msg.type.should.eql('connect');
 748          ws2.connected = true;
 749        } else {
 750          msg.should.eql({
 751              type: 'json'
 752            , data: 123
 753            , endpoint: ''
 754          });
 755
 756          messages++;
 757        }
 758      });
 759
 760      setTimeout(function () {
 761        ws2.finishClose();
 762      }, 50);
 763    });
 764
 765    cl3.handshake(function (sid) {
 766      var ws3 = websocket(cl3, sid);
 767      ws3.on('message', function (msg) {
 768        if (!ws3.connected) {
 769          msg.type.should.eql('connect');
 770          ws3.connected = true;
 771        } else {
 772          msg.should.eql({
 773              type: 'json'
 774            , data: 123
 775            , endpoint: ''
 776          });
 777
 778          messages++;
 779        }
 780      });
 781
 782      setTimeout(function () {
 783        ws3.finishClose();
 784      }, 50);
 785    });
 786  },
 787
 788  'test emitting to all clients in a room': function (done) {
 789    var port = ++ports
 790      , cl1 = client(port)
 791      , cl2 = client(port)
 792      , cl3 = client(port)
 793      , io = create(cl1)
 794      , messages = 0
 795      , joins = 0
 796      , connections = 0
 797      , disconnections = 0;
 798
 799    io.configure(function () {
 800      io.set('close timeout', 0);
 801    });
 802
 803    io.sockets.on('connection', function (socket) {
 804      connections++;
 805
 806      if (connections != 3) {
 807        socket.join('woot');
 808        joins++;
 809
 810        if (joins == 2) {
 811          setTimeout(function () {
 812            connections.should.eql(3);
 813            io.sockets.in('woot').emit('locki');
 814          }, 20);
 815        }
 816      }
 817
 818      socket.on('disconnect', function () {
 819        disconnections++;
 820
 821        if (disconnections == 3) {
 822          messages.should.eql(2);
 823          cl1.end();
 824          cl2.end();
 825          cl3.end();
 826          io.server.close();
 827          done();
 828        }
 829      });
 830    });
 831
 832    cl1.handshake(function (sid) {
 833      var ws1 = websocket(cl1, sid);
 834      ws1.on('message', function (msg) {
 835        if (!ws1.connected) {
 836          msg.type.should.eql('connect');
 837          ws1.connected = true;
 838        } else {
 839          msg.should.eql({
 840              type: 'event'
 841            , name: 'locki'
 842            , args: []
 843            , endpoint: ''
 844          });
 845
 846          messages++;
 847        }
 848      });
 849
 850      setTimeout(function () {
 851        ws1.finishClose();
 852      }, 50);
 853    });
 854
 855    cl2.handshake(function (sid) {
 856      var ws2 = websocket(cl2, sid);
 857      ws2.on('message', function (msg) {
 858        if (!ws2.connected) {
 859          msg.type.should.eql('connect');
 860          ws2.connected = true;
 861        } else {
 862          msg.should.eql({
 863              type: 'event'
 864            , name: 'locki'
 865            , args: []
 866            , endpoint: ''
 867          });
 868
 869          messages++;
 870        }
 871      });
 872
 873      setTimeout(function () {
 874        ws2.finishClose();
 875      }, 50);
 876    });
 877
 878    cl3.handshake(function (sid) {
 879      var ws3 = websocket(cl3, sid);
 880      ws3.on('message', function (msg) {
 881        if (!ws3.connected) {
 882          msg.type.should.eql('connect');
 883          ws3.connected = true;
 884        } else {
 885          msg.should.eql({
 886              type: 'event'
 887            , name: 'locki'
 888            , args: []
 889            , endpoint: ''
 890          });
 891
 892          messages++;
 893        }
 894      });
 895
 896      setTimeout(function () {
 897        ws3.finishClose();
 898      }, 50);
 899    });
 900  },
 901
 902  'test leaving a room': function (done) {
 903    var port = ++ports
 904      , cl1 = client(port)
 905      , cl2 = client(port)
 906      , io = create(cl1)
 907      , joins = 0
 908      , disconnects = 0;
 909
 910    io.set('close timeout', 0);
 911
 912    io.sockets.on('connection', function (socket) {
 913      socket.join('foo');
 914      io.sockets.clients('foo').should.have.length(++joins);
 915
 916      socket.on('disconnect', function () {
 917        socket.leave('foo');
 918        socket.leave('foo');
 919        socket.leave('foo');
 920
 921        io.sockets.clients('foo').should.have.length(--joins);
 922
 923        if (++disconnects == 2) {
 924          io.server.close();
 925          cl1.end();
 926          cl2.end();
 927          done();
 928        }
 929      })
 930    });
 931
 932    cl1.handshake(function (sid) {
 933      var ws1 = websocket(cl1, sid);
 934      ws1.on('message', function (msg) {
 935        if (!ws1.connected) {
 936          msg.type.should.eql('connect');
 937          ws1.connected = true;
 938           ws1.finishClose();
 939        }
 940      });
 941    });
 942
 943    cl2.handshake(function (sid) {
 944      var ws2 = websocket(cl2, sid);
 945      ws2.on('message', function (msg) {
 946        if (!ws2.connected) {
 947          msg.type.should.eql('connect');
 948          ws2.connected = true;
 949          ws2.finishClose();
 950        }
 951      });
 952    });
 953  },
 954
 955  'test message with broadcast flag': function (done) {
 956    var port = ++ports
 957      , cl1 = client(port)
 958      , cl2 = client(port)
 959      , cl3 = client(port)
 960      , io = create(cl1)
 961      , messages = 0
 962      , disconnections = 0;
 963
 964    io.configure(function () {
 965      io.set('close timeout', 0);
 966    });
 967
 968    io.sockets.on('connection', function (socket) {
 969      socket.on('trigger broadcast', function () {
 970        socket.broadcast.send('boom');
 971      });
 972
 973      socket.on('disconnect', function () {
 974        disconnections++;
 975
 976        if (disconnections == 3) {
 977          messages.should.eql(2);
 978          cl1.end();
 979          cl2.end();
 980          cl3.end();
 981          io.server.close();
 982          done();
 983        }
 984      });
 985    });
 986
 987    cl1.handshake(function (sid) {
 988      var ws1 = websocket(cl1, sid);
 989      ws1.on('message', function (msg) {
 990        if (!ws1.connected) {
 991          msg.type.should.eql('connect');
 992          ws1.connected = true;
 993        } else {
 994          msg.should.eql({
 995              type: 'message'
 996            , data: 'boom'
 997            , endpoint: ''
 998          });
 999
1000          messages++;
1001          ws1.finishClose();
1002        }
1003      });
1004    });
1005
1006    cl2.handshake(function (sid) {
1007      var ws2 = websocket(cl2, sid);
1008      ws2.on('message', function (msg) {
1009        if (!ws2.connected) {
1010          msg.type.should.eql('connect');
1011          ws2.connected = true;
1012        } else {
1013          msg.should.eql({
1014              type: 'message'
1015            , data: 'boom'
1016            , endpoint: ''
1017          });
1018
1019          messages++;
1020          ws2.finishClose();
1021        }
1022      });
1023    });
1024
1025    cl3.handshake(function (sid) {
1026      var ws3 = websocket(cl3, sid);
1027      ws3.on('open', function () {
1028        ws3.packet({
1029            type: 'event'
1030          , name: 'trigger broadcast'
1031          , endpoint: ''
1032        });
1033
1034        setTimeout(function () {
1035          ws3.finishClose();
1036        }, 50);
1037      });
1038
1039      ws3.on('message', function (msg) {
1040        if (!ws3.connected) {
1041          msg.type.should.eql('connect');
1042          ws3.connected = true;
1043        } else {
1044          throw new Error('we shouldnt get a message here');
1045        }
1046      });
1047    });
1048  },
1049
1050  'test json with broadcast flag': function (done) {
1051    var port = ++ports
1052      , cl1 = client(port)
1053      , cl2 = client(port)
1054      , cl3 = client(port)
1055      , io = create(cl1)
1056      , messages = 0
1057      , disconnections = 0;
1058
1059    io.configure(function () {
1060      io.set('close timeout', 0);
1061    });
1062
1063    io.sockets.on('connection', function (socket) {
1064      socket.on('trigger broadcast', function () {
1065        socket.broadcast.json.send([1, 2, 3]);
1066      });
1067
1068      socket.on('disconnect', function () {
1069        disconnections++;
1070
1071        if (disconnections == 3) {
1072          messages.should.eql(2);
1073          cl1.end();
1074          cl2.end();
1075          cl3.end();
1076          io.server.close();
1077          done();
1078        }
1079      });
1080    });
1081
1082    cl1.handshake(function (sid) {
1083      var ws1 = websocket(cl1, sid);
1084      ws1.on('message', function (msg) {
1085        if (!ws1.connected) {
1086          msg.type.should.eql('connect');
1087          ws1.connected = true;
1088        } else {
1089          msg.should.eql({
1090              type: 'json'
1091            , data: [1, 2, 3]
1092            , endpoint: ''
1093          });
1094
1095          messages++;
1096          ws1.finishClose();
1097        }
1098      });
1099    });
1100
1101    cl2.handshake(function (sid) {
1102      var ws2 = websocket(cl2, sid);
1103      ws2.on('message', function (msg) {
1104        if (!ws2.connected) {
1105          msg.type.should.eql('connect');
1106          ws2.connected = true;
1107        } else {
1108          msg.should.eql({
1109              type: 'json'
1110            , data: [1, 2, 3]
1111            , endpoint: ''
1112          });
1113
1114          messages++;
1115          ws2.finishClose();
1116        }
1117      });
1118    });
1119
1120    cl3.handshake(function (sid) {
1121      var ws3 = websocket(cl3, sid);
1122      ws3.on('open', function () {
1123        ws3.packet({
1124            type: 'event'
1125          , name: 'trigger broadcast'
1126          , endpoint: ''
1127        });
1128
1129        setTimeout(function () {
1130          ws3.finishClose();
1131        }, 50);
1132      });
1133
1134      ws3.on('message', function (msg) {
1135        if (!ws3.connected) {
1136          msg.type.should.eql('connect');
1137          ws3.connected = true;
1138        } else {
1139          throw new Error('we shouldnt get a message here');
1140        }
1141      });
1142    });
1143  },
1144
1145  'test event with broadcast flag': function (done) {
1146    var port = ++ports
1147      , cl1 = client(port)
1148      , cl2 = client(port)
1149      , cl3 = client(port)
1150      , io = create(cl1)
1151      , messages = 0
1152      , disconnections = 0;
1153
1154    io.configure(function () {
1155      io.set('close timeout', 0);
1156    });
1157
1158    io.sockets.on('connection', function (socket) {
1159      socket.on('trigger broadcast', function () {
1160        socket.broadcast.emit('hey', 'arnold');
1161      });
1162
1163      socket.on('disconnect', function () {
1164        disconnections++;
1165
1166        if (disconnections == 3) {
1167          messages.should.eql(2);
1168          cl1.end();
1169          cl2.end();
1170          cl3.end();
1171          io.server.close();
1172          done();
1173        }
1174      });
1175    });
1176
1177    cl1.handshake(function (sid) {
1178      var ws1 = websocket(cl1, sid);
1179      ws1.on('message', function (msg) {
1180        if (!ws1.connected) {
1181          msg.type.should.eql('connect');
1182          ws1.connected = true;
1183        } else {
1184          msg.should.eql({
1185              type: 'event'
1186            , name: 'hey'
1187            , args: ['arnold']
1188            , endpoint: ''
1189          });
1190
1191          messages++;
1192          ws1.finishClose();
1193        }
1194      });
1195    });
1196
1197    cl2.handshake(function (sid) {
1198      var ws2 = websocket(cl2, sid);
1199      ws2.on('message', function (msg) {
1200        if (!ws2.connected) {
1201          msg.type.should.eql('connect');
1202          ws2.connected = true;
1203        } else {
1204          msg.should.eql({
1205              type: 'event'
1206            , name: 'hey'
1207            , args: ['arnold']
1208            , endpoint: ''
1209          });
1210
1211          messages++;
1212          ws2.finishClose();
1213        }
1214      });
1215    });
1216
1217    cl3.handshake(function (sid) {
1218      var ws3 = websocket(cl3, sid);
1219      ws3.on('open', function () {
1220        ws3.packet({
1221            type: 'event'
1222          , name: 'trigger broadcast'
1223          , endpoint: ''
1224        });
1225
1226        setTimeout(function () {
1227          ws3.finishClose();
1228        }, 50);
1229      });
1230
1231      ws3.on('message', function (msg) {
1232        if (!ws3.connected) {
1233          msg.type.should.eql('connect');
1234          ws3.connected = true;
1235        } else {
1236          throw new Error('we shouldnt get a message here');
1237        }
1238      });
1239    });
1240  },
1241
1242  'test message with broadcast flag and to()': function (done) {
1243    var port = ++ports
1244      , cl1 = client(port)
1245      , cl2 = client(port)
1246      , cl3 = client(port)
1247      , io = create(cl1)
1248      , messages = 0
1249      , connections = 0
1250      , disconnections = 0;
1251
1252    io.configure(function () {
1253      io.set('close timeout', 0);
1254    });
1255
1256    io.sockets.on('connection', function (socket) {
1257      connections++;
1258
1259      if (connections == 1) {
1260        socket.join('losers');
1261      }
1262
1263      socket.on('trigger broadcast', function () {
1264        socket.broadcast.to('losers').send('boom');
1265      });
1266
1267      socket.on('disconnect', function () {
1268        disconnections++;
1269
1270        if (disconnections == 3) {
1271          messages.should.eql(1);
1272          cl1.end();
1273          cl2.end();
1274          cl3.end();
1275          io.server.close();
1276          done();
1277        }
1278      });
1279    });
1280
1281    cl1.handshake(function (sid) {
1282      var ws1 = websocket(cl1, sid);
1283      ws1.on('message', function (msg) {
1284        if (!ws1.connected) {
1285          msg.type.should.eql('connect');
1286          ws1.connected = true;
1287        } else {
1288          msg.should.eql({
1289              type: 'message'
1290            , data: 'boom'
1291            , endpoint: ''
1292          });
1293
1294          messages++;
1295        }
1296      });
1297
1298      ws1.on('open', function () {
1299        cl2.handshake(function (sid) {
1300          var ws2 = websocket(cl2, sid);
1301          ws2.on('message', function (msg) {
1302            if (!ws2.connected) {
1303              msg.type.should.eql('connect');
1304              ws2.connected = true;
1305            } else {
1306              throw new Error('This socket shouldnt get a message');
1307            }
1308          });
1309
1310          ws2.on('open', function () {
1311            cl3.handshake(function (sid) {
1312              var ws3 = websocket(cl3, sid);
1313              ws3.on('open', function () {
1314                ws3.packet({
1315                    type: 'event'
1316                  , name: 'trigger broadcast'
1317                  , endpoint: ''
1318                });
1319
1320                setTimeout(function () {
1321                  ws1.finishClose();
1322                  ws2.finishClose();
1323                  ws3.finishClose();
1324                }, 50);
1325              });
1326
1327              ws3.on('message', function (msg) {
1328                if (!ws3.connected) {
1329                  msg.type.should.eql('connect');
1330                  ws3.connected = true;
1331                } else {
1332                  throw new Error('we shouldnt get a message here');
1333                }
1334              });
1335            });
1336          });
1337        });
1338      });
1339    });
1340  },
1341
1342  'test json with broadcast flag and to()': function (done) {
1343    var port = ++ports
1344      , cl1 = client(port)
1345      , cl2 = client(port)
1346      , cl3 = client(port)
1347      , io = create(cl1)
1348      , messages = 0
1349      , connections = 0
1350      , disconnections = 0;
1351
1352    io.configure(function () {
1353      io.set('close timeout', 0);
1354    });
1355
1356    io.sockets.on('connection', function (socket) {
1357      connections++;
1358
1359      if (connections == 1) {
1360        socket.join('losers');
1361      }
1362
1363      socket.on('trigger broadcast', function () {
1364        socket.broadcast.json.to('losers').send({ hello: 'world' });
1365      });
1366
1367      socket.on('disconnect', function () {
1368        disconnections++;
1369
1370        if (disconnections == 3) {
1371          messages.should.eql(1);
1372          cl1.end();
1373          cl2.end();
1374          cl3.end();
1375          io.server.close();
1376          done();
1377        }
1378      });
1379    });
1380
1381    cl1.handshake(function (sid) {
1382      var ws1 = websocket(cl1, sid);
1383      ws1.on('message', function (msg) {
1384        if (!ws1.connected) {
1385          msg.type.should.eql('connect');
1386          ws1.connected = true;
1387        } else {
1388          msg.should.eql({
1389              type: 'json'
1390            , data: { hello: 'world' }
1391            , endpoint: ''
1392          });
1393
1394          messages++;
1395        }
1396      });
1397
1398      ws1.on('open', function () {
1399        cl2.handshake(function (sid) {
1400          var ws2 = websocket(cl2, sid);
1401          ws2.on('message', function (msg) {
1402            if (!ws2.connected) {
1403              msg.type.should.eql('connect');
1404              ws2.connected = true;
1405            } else {
1406              throw new Error('This socket shouldnt get a message');
1407            }
1408          });
1409
1410          ws2.on('open', function () {
1411            cl3.handshake(function (sid) {
1412              var ws3 = websocket(cl3, sid);
1413              ws3.on('open', function () {
1414                ws3.packet({
1415                    type: 'event'
1416                  , name: 'trigger broadcast'
1417                  , endpoint: ''
1418                });
1419
1420                setTimeout(function () {
1421                  ws1.finishClose();
1422                  ws2.finishClose();
1423                  ws3.finishClose();
1424                }, 50);
1425              });
1426
1427              ws3.on('message', function (msg) {
1428                if (!ws3.connected) {
1429                  msg.type.should.eql('connect');
1430                  ws3.connected = true;
1431                } else {
1432                  throw new Error('we shouldnt get a message here');
1433                }
1434              });
1435            });
1436          });
1437        });
1438      });
1439    });
1440  },
1441
1442  'test event with broadcast flag and to()': function (done) {
1443    var port = ++ports
1444      , cl1 = client(port)
1445      , cl2 = client(port)
1446      , cl3 = client(port)
1447      , io = create(cl1)
1448      , messages = 0
1449      , connections = 0
1450      , disconnections = 0;
1451
1452    io.configure(function () {
1453      io.set('close timeout', 0);
1454    });
1455
1456    io.sockets.on('connection', function (socket) {
1457      connections++;
1458
1459      if (connections == 1) {
1460        socket.join('losers');
1461      }
1462
1463      socket.on('trigger broadcast', function () {
1464        socket.broadcast.to('losers').emit('victory');
1465      });
1466
1467      socket.on('disconnect', function () {
1468        disconnections++;
1469
1470        if (disconnections == 3) {
1471          messages.should.eql(1);
1472          cl1.end();
1473          cl2.end();
1474          cl3.end();
1475          io.server.close();
1476          done();
1477        }
1478      });
1479    });
1480
1481    cl1.handshake(function (sid) {
1482      var ws1 = websocket(cl1, sid);
1483      ws1.on('message', function (msg) {
1484        if (!ws1.connected) {
1485          msg.type.should.eql('connect');
1486          ws1.connected = true;
1487        } else {
1488          msg.should.eql({
1489              type: 'event'
1490            , name: 'victory'
1491            , args: []
1492            , endpoint: ''
1493          });
1494
1495          messages++;
1496        }
1497      });
1498
1499      ws1.on('open', function () {
1500        cl2.handshake(function (sid) {
1501          var ws2 = websocket(cl2, sid);
1502          ws2.on('message', function (msg) {
1503            if (!ws2.connected) {
1504              msg.type.should.eql('connect');
1505              ws2.connected = true;
1506            } else {
1507              throw new Error('This socket shouldnt get a message');
1508            };
1509          });
1510
1511          ws2.on('open', function () {
1512            cl3.handshake(function (sid) {
1513              var ws3 = websocket(cl3, sid);
1514              ws3.on('open', function () {
1515                ws3.packet({
1516                    type: 'event'
1517                  , name: 'trigger broadcast'
1518                  , endpoint: ''
1519                });
1520
1521                setTimeout(function () {
1522                  ws1.finishClose();
1523                  ws2.finishClose();
1524                  ws3.finishClose();
1525                }, 50);
1526              });
1527
1528              ws3.on('message', function (msg) {
1529                if (!ws3.connected) {
1530                  msg.type.should.eql('connect');
1531                  ws3.connected = true;
1532                } else {
1533                  throw new Error('we shouldnt get a message here');
1534                }
1535              });
1536            });
1537          });
1538        });
1539      });
1540    });
1541  },
1542
1543  'test accessing handshake data from sockets': function (done) {
1544    var cl = client(++ports)
1545      , io = create(cl)
1546      , ws;
1547
1548    io.sockets.on('connection', function (socket) {
1549      (!!socket.handshake.address.address).should.be.true;
1550      (!!socket.handshake.address.port).should.be.true;
1551      socket.handshake.headers.host.should.equal('localhost');
1552      socket.handshake.headers.connection.should.equal('keep-alive');
1553      socket.handshake.time.should.match(/GMT/);
1554
1555      socket.on('disconnect', function () {
1556        setTimeout(function () {
1557          ws.finishClose();
1558          cl.end();
1559          io.server.close();
1560          done();
1561        }, 10);
1562      });
1563
1564      socket.disconnect();
1565    });
1566
1567    cl.handshake(function (sid) {
1568      ws = websocket(cl, sid);
1569      ws.on('message', function (msg) {
1570        if (!ws.connected) {
1571          msg.type.should.eql('connect');
1572          ws.connected = true;
1573        }
1574      });
1575    });
1576  },
1577
1578  'test accessing the array of clients': function (done) {
1579    var port = ++ports
1580      , cl1 = client(port)
1581      , cl2 = client(port)
1582      , io = create(cl1)
1583      , total = 2
1584      , ws1, ws2;
1585
1586    io.sockets.on('connection', function (socket) {
1587      socket.on('join ferrets', function () {
1588        socket.join('ferrets');
1589        socket.send('done');
1590      });
1591    });
1592
1593    function check() {
1594      io.sockets.clients('ferrets').should.have.length(1);
1595      io.sockets.clients('ferrets')[0].should.be.an.instanceof(sio.Socket);
1596      io.sockets.clients('ferrets')[0].id.should.equal(ws1.sid);
1597      io.sockets.clients().should.have.length(2);
1598      io.sockets.clients()[0].should.be.an.instanceof(sio.Socket);
1599      io.sockets.clients()[0].id.should.equal(ws1.sid);
1600      io.sockets.clients()[1].should.be.an.instanceof(sio.Socket);
1601      io.sockets.clients()[1].id.should.equal(ws2.sid);
1602
1603      ws1.finishClose();
1604      ws2.finishClose();
1605      cl1.end();
1606      cl2.end();
1607      io.server.close();
1608      done();
1609    };
1610
1611    cl1.handshake(function (sid) {
1612      ws1 = websocket(cl1, sid);
1613      ws1.sid = sid;
1614      ws1.on('message', function (msg) {
1615        if (!ws1.connected) {
1616          msg.type.should.eql('connect');
1617          ws1.connected = true;
1618          ws1.packet({
1619              type: 'event'
1620            , name: 'join ferrets'
1621            , endpoint: ''
1622          });
1623        } else {
1624          cl2.handshake(function (sid) {
1625            ws2 = websocket(cl2, sid);
1626            ws2.sid = sid;
1627            ws2.on('message', function (msg) {
1628              if (!ws2.connected) {
1629                msg.type.should.eql('connect');
1630                ws2.connected = true;
1631                check();
1632              }
1633            });
1634          });
1635        }
1636      });
1637    });
1638  },
1639
1640  'test accessing handshake data from sockets on disconnect': function (done) {
1641    var cl = client(++ports)
1642      , io = create(cl)
1643      , ws;
1644
1645    io.sockets.on('connection', function (socket) {
1646      socket.on('disconnect', function () {
1647
1648      (!!socket.handshake.address.address).should.be.true;
1649      (!!socket.handshake.address.port).should.be.true;
1650      socket.handshake.headers.host.should.equal('localhost');
1651      socket.handshake.headers.connection.should.equal('keep-alive');
1652      socket.handshake.time.should.match(/GMT/);
1653
1654        setTimeout(function () {
1655          ws.finishClose();
1656          cl.end();
1657          io.server.close();
1658          done();
1659        }, 10);
1660      });
1661
1662      socket.disconnect();
1663    });
1664
1665    cl.handshake(function (sid) {
1666      ws = websocket(cl, sid);
1667      ws.on('message', function (msg) {
1668        if (!ws.connected) {
1669          msg.type.should.eql('connect');
1670          ws.connected = true;
1671        }
1672      });
1673    });
1674  },
1675
1676  'test for intentional and unintentional disconnects': function (done) {
1677    var cl = client(++ports)
1678      , io = create(cl)
1679      , calls = 0
1680      , ws;
1681
1682    function close () {
1683      cl.end();
1684      io.server.close();
1685      ws.finishClose();
1686      done();
1687    }
1688
1689    io.configure(function () {
1690      io.set('heartbeat interval', .05);
1691      io.set('heartbeat timeout', .05);
1692      io.set('close timeout', 0);
1693    });
1694
1695    io.of('/foo').on('connection', function (socket) {
1696      socket.on('disconnect', function (reason) {
1697       reason.should.equal('packet');
1698
1699       if (++calls == 2) close();
1700      });
1701    });
1702
1703    io.of('/bar').on('connection', function (socket) {
1704      socket.on('disconnect', function (reason) {
1705        reason.should.equal('socket end');
1706
1707        if (++calls == 2) close();
1708      });
1709    });
1710
1711    cl.handshake(function (sid) {
1712      var messages = 0;
1713      ws = websocket(cl, sid);
1714      ws.on('open', function () {
1715        ws.packet({
1716            type: 'connect'
1717          , endpoint: '/foo'
1718        });
1719        ws.packet({
1720            type: 'connect'
1721          , endpoint: '/bar'
1722        });
1723      });
1724
1725      ws.on('message', function (packet) {
1726        if (packet.type == 'connect') {
1727          if (++messages === 3) {
1728            ws.packet({ type: 'disconnect', endpoint:'/foo' });
1729            ws.finishClose();
1730          }
1731        }
1732      });
1733    });
1734  },
1735
1736  'test socket clean up': function (done) {
1737    var cl = client(++ports)
1738      , io = create(cl)
1739      , ws;
1740
1741    io.sockets.on('connection', function (socket) {
1742      var self = this
1743        , id = socket.id;
1744
1745      socket.on('disconnect', function () {
1746        setTimeout(function () {
1747          var available = !!self.sockets[id];
1748
1749          available.should.be.false;
1750          ws.finishClose();
1751          cl.end();
1752          io.server.close();
1753          done();
1754        }, 10);
1755      });
1756
1757      socket.disconnect();
1758    });
1759
1760    cl.handshake(function (sid) {
1761      ws = websocket(cl, sid);
1762      ws.on('message', function (msg) {
1763        if (!ws.connected) {
1764          msg.type.should.eql('connect');
1765          ws.connected = true;
1766        }
1767      });
1768    });
1769  },
1770
1771};