mirror of
https://github.com/gundb/panic-server.git
synced 2026-01-13 23:37:54 -05:00
277 lines
7.0 KiB
JavaScript
277 lines
7.0 KiB
JavaScript
/*globals beforeEach, describe, it*/
|
|
'use strict';
|
|
var mock = require('./mock');
|
|
var Client = mock.Client;
|
|
var ClientList = require('../src/ClientList');
|
|
var Promise = require('bluebird');
|
|
|
|
var expect = require('chai').expect;
|
|
|
|
describe('A clientList', function () {
|
|
var list, client;
|
|
beforeEach(function () {
|
|
list = new ClientList();
|
|
client = new Client({
|
|
name: 'Node.js'
|
|
});
|
|
});
|
|
|
|
it('should emit when a client is added', function () {
|
|
var fired = false;
|
|
list.on('add', function () {
|
|
fired = true;
|
|
}).add(client);
|
|
expect(fired).to.eq(true);
|
|
});
|
|
|
|
it('should emit when a client is removed', function () {
|
|
var fired = false;
|
|
list.on('remove', function () {
|
|
fired = true;
|
|
})
|
|
.add(client)
|
|
.remove(client);
|
|
expect(fired).to.eq(true);
|
|
});
|
|
|
|
it('should return length when "len()" is called', function () {
|
|
list.add(client);
|
|
expect(list.length).to.eq(1);
|
|
list.remove(client);
|
|
expect(list.length).to.eq(0);
|
|
});
|
|
|
|
it('should not add disconnected clients', function () {
|
|
client.socket.connected = false;
|
|
list.add(client);
|
|
expect(list.length).to.eq(0);
|
|
});
|
|
|
|
it('should remove a client on disconnect', function () {
|
|
list.add(client);
|
|
expect(list.length).to.eq(1);
|
|
client.socket.emit('disconnect');
|
|
expect(list.length).to.eq(0);
|
|
});
|
|
|
|
it('should resolve a promise when all clients finish', function (done) {
|
|
client.socket.on('run', function (cb, jobID) {
|
|
client.socket.emit(jobID);
|
|
});
|
|
list.add(client).run(function () {})
|
|
.then(function () {
|
|
done();
|
|
})
|
|
.catch(done);
|
|
});
|
|
|
|
it('should reject a promise if an error is sent', function (done) {
|
|
client.socket.on('run', function (cb, job) {
|
|
client.socket.emit(job, 'fake error');
|
|
});
|
|
list.add(client).run(function () {})
|
|
.catch(function (err) {
|
|
expect(err).to.eq('fake error');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should not emit "add" if it contains the client', function () {
|
|
var called = 0;
|
|
list.on('add', function () {
|
|
called += 1;
|
|
});
|
|
list.add(client);
|
|
list.add(client);
|
|
expect(called).to.eq(1);
|
|
});
|
|
|
|
describe('filter', function () {
|
|
it('should not mutate the original list', function () {
|
|
list.add(client);
|
|
expect(list.length).to.eq(1);
|
|
list.filter(function () {
|
|
return false;
|
|
});
|
|
expect(list.length).to.eq(1);
|
|
});
|
|
|
|
it('should return a new, filtered list', function () {
|
|
list.add(client);
|
|
var servers = list.filter('Node.js');
|
|
var browsers = list.filter(function (client) {
|
|
return client.platform.name !== 'Node.js';
|
|
});
|
|
expect(servers.length).to.eq(1);
|
|
expect(browsers.length).to.eq(0);
|
|
});
|
|
|
|
it('should be reactive to changes to the parent list', function () {
|
|
var servers = list.filter('Node.js');
|
|
expect(servers.length).to.eq(0);
|
|
list.add(client);
|
|
expect(servers.length).to.eq(1);
|
|
});
|
|
});
|
|
|
|
describe('exclusion', function () {
|
|
it('should not contain excluded clients', function () {
|
|
list.add(client);
|
|
var filtered = list.excluding(list);
|
|
expect(filtered.length).to.eq(0);
|
|
});
|
|
|
|
it('should react to removals if they are connected', function () {
|
|
var decoy = new Client();
|
|
var exclusion = new ClientList()
|
|
.add(client)
|
|
.add(decoy);
|
|
var filtered = list.excluding(exclusion);
|
|
list.add(client).add(new Client());
|
|
expect(filtered.length).to.eq(1);
|
|
exclusion.remove(client).remove(decoy);
|
|
expect(filtered.length).to.eq(2);
|
|
});
|
|
});
|
|
|
|
describe('number constraint', function () {
|
|
it('should return no more than the number requested', function () {
|
|
list.add(client)
|
|
.add(new Client())
|
|
.add(new Client());
|
|
expect(list.pluck(1).length).to.eq(1);
|
|
});
|
|
|
|
it('should listen for additions', function () {
|
|
var subset = list.pluck(2);
|
|
expect(subset.length).not.to.eq(2);
|
|
list.add(new Client()).add(new Client());
|
|
expect(subset.length).to.eq(2);
|
|
list.add(new Client());
|
|
expect(subset.length).to.eq(2);
|
|
});
|
|
|
|
it('should replace a client when it disconnects', function () {
|
|
var subset = list.pluck(1);
|
|
list.add(client).add(new Client());
|
|
expect(subset.length).to.eq(1);
|
|
client.socket.emit('disconnect');
|
|
// It should be replaced with
|
|
// the second connected client.
|
|
expect(subset.length).to.eq(1);
|
|
});
|
|
|
|
it('should set a flag whether the constraint is met', function () {
|
|
var subset = list.pluck(1);
|
|
expect(subset.atCapacity).to.eq(false);
|
|
list.add(client);
|
|
expect(subset.atCapacity).to.eq(true);
|
|
client.socket.emit('disconnect');
|
|
expect(subset.atCapacity).to.eq(false);
|
|
});
|
|
|
|
it('should play well with exclusions', function () {
|
|
var bob, alice = list.pluck(1);
|
|
bob = list.excluding(alice).pluck(1);
|
|
list.add(client)
|
|
.add(new Client())
|
|
.add(new Client());
|
|
expect(alice.length).to.eq(1);
|
|
expect(bob.length).to.eq(1);
|
|
});
|
|
});
|
|
|
|
describe('minimum qualifier', function () {
|
|
|
|
it('should resolve when the minimum is reached', function () {
|
|
var promise = list.atLeast(1);
|
|
var called = false;
|
|
promise.then(function () {
|
|
called = true;
|
|
});
|
|
expect(called).to.eq(false);
|
|
list.add(new Client());
|
|
|
|
// Mocha will wait for this to resolve.
|
|
return promise;
|
|
});
|
|
|
|
it('should resolve if the min is already reached', function () {
|
|
var promise = list.atLeast(0);
|
|
|
|
// This will time out if unresolved.
|
|
return promise;
|
|
});
|
|
|
|
it('should resolve to undefined', function () {
|
|
function validate (arg) {
|
|
expect(arg).to.eq(undefined);
|
|
}
|
|
var immediate = list.atLeast(0).then(validate);
|
|
var later = list.atLeast(1).then(validate);
|
|
|
|
list.add(new Client());
|
|
|
|
return Promise.all([immediate, later]);
|
|
});
|
|
|
|
it('should resolve if it has more than enough', function () {
|
|
list.add(new Client()).add(new Client());
|
|
|
|
return list.atLeast(1);
|
|
});
|
|
|
|
it('should unsubscribe after resolving', function () {
|
|
list.atLeast(1);
|
|
expect(list.listenerCount('add')).to.eq(1);
|
|
list.add(new Client());
|
|
expect(list.listenerCount('add')).to.eq(0);
|
|
});
|
|
|
|
});
|
|
});
|
|
|
|
describe('The ClientList constructor', function () {
|
|
var list1, list2, client1, client2;
|
|
|
|
beforeEach(function () {
|
|
list1 = new ClientList();
|
|
list2 = new ClientList();
|
|
client1 = new Client();
|
|
client2 = new Client();
|
|
list1.add(client1);
|
|
list2.add(client2);
|
|
});
|
|
|
|
it('should accept an array of clientLists', function () {
|
|
var list = new ClientList([list1, list2]);
|
|
|
|
// it should contain both clients
|
|
expect(list.get(client1.socket.id)).to.eq(client1);
|
|
expect(list.get(client2.socket.id)).to.eq(client2);
|
|
});
|
|
|
|
it('should reactively add new clients from source lists', function () {
|
|
var list = new ClientList([list1, list2]);
|
|
var client3 = new Client();
|
|
expect(list.get(client3.socket.id)).to.eq(null);
|
|
list1.add(client3);
|
|
expect(list.get(client3.socket.id)).to.eq(client3);
|
|
});
|
|
|
|
it('should be subclassable', function () {
|
|
function Sub() {
|
|
ClientList.call(this);
|
|
}
|
|
Sub.prototype = new ClientList();
|
|
Sub.prototype.constructor = Sub;
|
|
|
|
var sub = new Sub();
|
|
expect(sub).to.be.an.instanceof(Sub);
|
|
|
|
// chained inheritance
|
|
expect(sub.filter('Firefox')).to.be.an.instanceof(Sub);
|
|
expect(sub.pluck(1)).to.be.an.instanceof(Sub);
|
|
});
|
|
});
|