Switch to idiomatic JS Event framework.

Remove Unity debugging, as we no longer have interested clients.
This commit is contained in:
Ian Gulliver
2015-05-31 18:00:07 -07:00
parent 014fde230a
commit 3fa24f803d
5 changed files with 352 additions and 398 deletions

View File

@@ -41,20 +41,11 @@ String.prototype.hashCode = function() {
/** /**
* @see https://www.cosmopolite.org/reference#constructor * @see https://www.cosmopolite.org/reference#constructor
* @constructor * @constructor
* @param {?Cosmopolite.typeCallbacks=} opt_callbacks
* @param {?string=} opt_urlPrefix * @param {?string=} opt_urlPrefix
* @param {?string=} opt_namespace * @param {?string=} opt_namespace
* @param {?string=} opt_trackingID * @param {?string=} opt_trackingID
*/ */
var Cosmopolite = function( var Cosmopolite = function(opt_urlPrefix, opt_namespace, opt_trackingID) {
opt_callbacks, opt_urlPrefix, opt_namespace, opt_trackingID) {
/**
* @type {Cosmopolite.typeCallbacks}
* @const
* @private
*/
this.callbacks_ =
opt_callbacks || /** @type {Cosmopolite.typeCallbacks} */ ({});
/** /**
* @type {string} * @type {string}
* @const * @const
@@ -119,6 +110,19 @@ var Cosmopolite = function(
*/ */
this.instanceID_ = this.uuid(); this.instanceID_ = this.uuid();
/**
* @type {DocumentFragment}
* @private
* Weep for all our souls.
*/
this.eventTarget_ = document.createDocumentFragment();
this.addEventListener =
this.eventTarget_.addEventListener.bind(this.eventTarget_);
this.removeEventListener =
this.eventTarget_.removeEventListener.bind(this.eventTarget_);
this.dispatchEvent =
this.eventTarget_.dispatchEvent.bind(this.eventTarget_);
/** /**
* @type {string} * @type {string}
* @const * @const
@@ -153,16 +157,6 @@ var Cosmopolite = function(
}; };
/** @typedef {{onConnect: (function()|undefined),
onDisconnect: (function()|undefined),
onLogin: (function(string, string)|undefined),
onLogout: (function(string)|undefined),
onMessage: (function(Cosmopolite.typeMessage)|undefined),
onPin: (function(Cosmopolite.typeMessage)|undefined),
onUnpin: (function(Cosmopolite.typeMessage)|undefined)}} */
Cosmopolite.typeCallbacks;
/** /**
* @typedef {{event_type: string}} * @typedef {{event_type: string}}
* @private * @private
@@ -396,11 +390,11 @@ Cosmopolite.prototype.unsubscribe = function(subject) {
*/ */
Cosmopolite.prototype.sendMessage = function(subject, message) { Cosmopolite.prototype.sendMessage = function(subject, message) {
return this.newPromise_(function(resolve, reject) { return this.newPromise_(function(resolve, reject) {
var args = { var args = /** @type {Cosmopolite.typeMessage} */ ({
'subject': this.canonicalSubject_(subject), 'subject': this.canonicalSubject_(subject),
'message': JSON.stringify(message), 'message': JSON.stringify(message),
'sender_message_id': this.uuid() 'sender_message_id': this.uuid()
}; });
// No message left behind. // No message left behind.
var messageQueue = JSON.parse(localStorage[this.messageQueueKey_]); var messageQueue = JSON.parse(localStorage[this.messageQueueKey_]);
@@ -868,7 +862,7 @@ Cosmopolite.prototype.onRPCResponse_ =
} }
// Handle events that were immediately available as if they came over the // Handle events that were immediately available as if they came over the
// channel. Fire them before the message callbacks, so clients can use // channel. Fire them before the message events, so clients can use
// events like the subscribe promise fulfillment as a barrier for initial // events like the subscribe promise fulfillment as a barrier for initial
// data. // data.
data['events'].forEach(this.onServerEvent_, this); data['events'].forEach(this.onServerEvent_, this);
@@ -1068,9 +1062,7 @@ Cosmopolite.prototype.onSocketOpen_ = function() {
if (this.channelState_ == Cosmopolite.ChannelState_.OPENING) { if (this.channelState_ == Cosmopolite.ChannelState_.OPENING) {
this.channelState_ = Cosmopolite.ChannelState_.OPEN; this.channelState_ = Cosmopolite.ChannelState_.OPEN;
if (this.callbacks_.onConnect) { this.onConnect_();
this.callbacks_.onConnect();
}
} else { } else {
return; return;
} }
@@ -1093,9 +1085,7 @@ Cosmopolite.prototype.onSocketClose_ = function() {
if (this.channelState_ == Cosmopolite.ChannelState_.OPEN) { if (this.channelState_ == Cosmopolite.ChannelState_.OPEN) {
this.channelState_ = Cosmopolite.ChannelState_.CLOSED; this.channelState_ = Cosmopolite.ChannelState_.CLOSED;
if (this.callbacks_.onDisconnect) { this.onDisconnect_();
this.callbacks_.onDisconnect();
}
} else { } else {
return; return;
} }
@@ -1155,6 +1145,34 @@ Cosmopolite.prototype.onClose_ = function() {
}; };
/**
* Callback on connection to server
*
* @private
*/
Cosmopolite.prototype.onConnect_ = function() {
var e = new CustomEvent('connect', {
'detail': {
}
});
this.dispatchEvent(e);
};
/**
* Callback on disconnection from server
*
* @private
*/
Cosmopolite.prototype.onDisconnect_ = function() {
var e = new CustomEvent('disconnect', {
'detail': {
}
});
this.dispatchEvent(e);
};
/** /**
* Callback on receiving a 'login' event from the server * Callback on receiving a 'login' event from the server
* *
@@ -1162,11 +1180,13 @@ Cosmopolite.prototype.onClose_ = function() {
* @private * @private
*/ */
Cosmopolite.prototype.onLogin_ = function(e) { Cosmopolite.prototype.onLogin_ = function(e) {
if (this.callbacks_.onLogin) { var e2 = new CustomEvent('login', {
this.callbacks_.onLogin( 'detail': {
e['google_user'], 'username': e['google_user'],
this.urlPrefix_ + '/auth/logout'); 'logout_url': this.urlPrefix_ + '/auth/logout'
} }
});
this.dispatchEvent(e2);
}; };
@@ -1177,10 +1197,12 @@ Cosmopolite.prototype.onLogin_ = function(e) {
* @private * @private
*/ */
Cosmopolite.prototype.onLogout_ = function(e) { Cosmopolite.prototype.onLogout_ = function(e) {
if (this.callbacks_.onLogout) { var e2 = new CustomEvent('logout', {
this.callbacks_.onLogout( 'detail': {
this.urlPrefix_ + '/auth/login'); 'login_url': this.urlPrefix_ + '/auth/login'
} }
});
this.dispatchEvent(e2);
}; };
@@ -1226,9 +1248,10 @@ Cosmopolite.prototype.onMessage_ = function(e) {
} }
subscription.messages.splice(insertAfter + 1, 0, e); subscription.messages.splice(insertAfter + 1, 0, e);
if (this.callbacks_.onMessage) { var e2 = new CustomEvent('message', {
this.callbacks_.onMessage(e); 'detail': e
} });
this.dispatchEvent(e2);
}; };
@@ -1260,9 +1283,11 @@ Cosmopolite.prototype.onPin_ = function(e) {
e['message'] = JSON.parse(e['message']); e['message'] = JSON.parse(e['message']);
subscription.pins.push(e); subscription.pins.push(e);
if (this.callbacks_.onPin) {
this.callbacks_.onPin(e); var e2 = new CustomEvent('pin', {
} 'detail': e
});
this.dispatchEvent(e2);
}; };
@@ -1298,9 +1323,11 @@ Cosmopolite.prototype.onUnpin_ = function(e) {
e['message'] = JSON.parse(e['message']); e['message'] = JSON.parse(e['message']);
subscription.pins.splice(index, 1); subscription.pins.splice(index, 1);
if (this.callbacks_.onUnpin) {
this.callbacks_.onUnpin(e); var e2 = new CustomEvent('unpin', {
} 'detail': e
});
this.dispatchEvent(e2);
}; };
@@ -1342,7 +1369,6 @@ Cosmopolite.prototype.onServerEvent_ = function(e) {
/** @type {function(new:Cosmopolite, /** @type {function(new:Cosmopolite,
?Cosmopolite.typeCallbacks=,
?string=, ?string=,
?string=)} */ ?string=)} */
window.Cosmopolite = Cosmopolite; window.Cosmopolite = Cosmopolite;

View File

@@ -1,79 +0,0 @@
<html>
<head>
<title>Cosmopolite Unity Demo</title>
<script type='text/javascript' src='https://ssl-webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/jquery.min.js'></script>
<script type='text/javascript' src='https://ssl-webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject.js'></script>
<script type="text/javascript" src="/cosmopolite/static/cosmopolite.js" charset="UTF-8"></script>
</head>
<body>
<div id="unityPlayer"></div>
<script type="text/javascript">
var gameObject;
var gameModuleName;
var messageQueue = [];
var onUnityLoad = function(obj) {
gameObject = obj.ref;
};
var sendUnityMessage = function(funcName, msg) {
msg = msg || '';
if (gameObject && gameModuleName) {
gameObject.SendMessage(gameModuleName, funcName, msg);
} else {
messageQueue.push([funcName, msg]);
}
};
var loginUrl, logoutUrl;
var doLogin = function() {
if (loginUrl) {
window.open(loginUrl);
}
};
var doLogout = function() {
if (logoutUrl) {
window.open(logoutUrl);
}
};
var registerGameObject = function(name) {
gameModuleName = name;
while (messageQueue.length) {
var item = messageQueue.shift();
sendUnityMessage(item[0], item[1]);
}
};
var pluginDidLoad = function() {
// Called by the Unity example code, but not used.
};
unityObject.embedUnity(
'unityPlayer',
'debug.unity3d',
500,
80,
null,
null,
onUnityLoad);
var callbacks = {
onLogin: function(username, logout_url) {
logoutUrl = logout_url;
sendUnityMessage('OnLogin', username);
},
onLogout: function(login_url) {
loginUrl = login_url;
sendUnityMessage('OnLogout');
},
onStateChange: function(key, value) {
},
};
var cosmo = new Cosmopolite(callbacks);
</script>
</body>
</html>

View File

@@ -23,16 +23,16 @@ var onReady = function() {
elements[elementIDs[i]] = document.getElementById(elementIDs[i]); elements[elementIDs[i]] = document.getElementById(elementIDs[i]);
} }
var callbacks = { cosmo = new Cosmopolite(null, null, 'UA-37845853-3');
'onConnect': onConnect,
'onDisconnect': onDisconnect, cosmo.addEventListener('connect', onConnect);
'onLogin': onLogin, cosmo.addEventListener('disconnect', onDisconnect);
'onLogout': onLogout, cosmo.addEventListener('login', onLogin);
'onMessage': onMessage, cosmo.addEventListener('logout', onLogout);
'onPin': onPin, cosmo.addEventListener('message', onMessage);
'onUnpin': onUnpin, cosmo.addEventListener('pin', onPin);
} cosmo.addEventListener('unpin', onUnpin);
cosmo = new Cosmopolite(callbacks, null, null, 'UA-37845853-3');
cosmo.trackEvent('send', 'pageview'); cosmo.trackEvent('send', 'pageview');
elements['messageText'].addEventListener('keypress', messageKeyPress); elements['messageText'].addEventListener('keypress', messageKeyPress);
@@ -57,22 +57,22 @@ var onDisconnect = function() {
document.createTextNode('Disconnected')); document.createTextNode('Disconnected'));
}; };
var onLogin = function(username, logout_url) { var onLogin = function(e) {
elements['loginStatus'].innerHTML = ''; elements['loginStatus'].innerHTML = '';
elements['loginStatus'].appendChild(document.createTextNode('Logged in')); elements['loginStatus'].appendChild(document.createTextNode('Logged in'));
elements['username'].innerHTML = ''; elements['username'].innerHTML = '';
elements['username'].appendChild(document.createTextNode(username)); elements['username'].appendChild(document.createTextNode(e.detail.username));
elements['loginAction'].innerHTML = ''; elements['loginAction'].innerHTML = '';
var link = document.createElement('a'); var link = document.createElement('a');
link.href = logout_url; link.href = e.detail.logout_url;
link.target = '_blank'; link.target = '_blank';
link.appendChild(document.createTextNode('Log out')); link.appendChild(document.createTextNode('Log out'));
elements['loginAction'].appendChild(link); elements['loginAction'].appendChild(link);
}; };
var onLogout = function(login_url) { var onLogout = function(e) {
elements['loginStatus'].innerHTML = ''; elements['loginStatus'].innerHTML = '';
elements['loginStatus'].appendChild( elements['loginStatus'].appendChild(
document.createTextNode('Not logged in')); document.createTextNode('Not logged in'));
@@ -81,25 +81,25 @@ var onLogout = function(login_url) {
elements['loginAction'].innerHTML = ''; elements['loginAction'].innerHTML = '';
var link = document.createElement('a'); var link = document.createElement('a');
link.href = login_url; link.href = e.detail.login_url;
link.target = '_blank'; link.target = '_blank';
link.appendChild(document.createTextNode('Log in')); link.appendChild(document.createTextNode('Log in'));
elements['loginAction'].appendChild(link); elements['loginAction'].appendChild(link);
}; };
var onMessage = function(msg) { var onMessage = function(e) {
addToList(msg, elements['messageList']); addToList(e.detail, elements['messageList']);
}; };
var onPin = function(msg) { var onPin = function(e) {
var item = addToList(msg, elements['pinList'], pins); var item = addToList(e.detail, elements['pinList'], pins);
if (msg['sender'] == cosmo.currentProfile()) { if (e.detail['sender'] == cosmo.currentProfile()) {
item.addEventListener('contextmenu', deletePin); item.addEventListener('contextmenu', deletePin);
} }
}; };
var onUnpin = function(msg) { var onUnpin = function(e) {
var item = pins[msg['id']]; var item = pins[e.detail['id']];
item.parentNode.removeChild(item); item.parentNode.removeChild(item);
}; };
@@ -114,10 +114,14 @@ var selectSubject = function() {
selectedSubject = this; selectedSubject = this;
elements['messageList'].innerHTML = ''; elements['messageList'].innerHTML = '';
cosmo.getMessages(this.subject).forEach(onMessage); cosmo.getMessages(this.subject).forEach(function(msg) {
onMessage({'detail': msg});
});
elements['pinList'].innerHTML = ''; elements['pinList'].innerHTML = '';
cosmo.getPins(this.subject).forEach(onPin); cosmo.getPins(this.subject).forEach(function(pin) {
onPin({'detail': pin});
});
}; };
var addToList = function(msg, list, trackobj) { var addToList = function(msg, list, trackobj) {

Binary file not shown.

View File

@@ -67,7 +67,7 @@ QUnit.module('All platforms');
QUnit.test('Construct/shutdown', function(assert) { QUnit.test('Construct/shutdown', function(assert) {
assert.expect(2); assert.expect(2);
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
assert.ok(true, 'new Cosmopolite() succeeds'); assert.ok(true, 'new Cosmopolite() succeeds');
cosmo.shutdown(); cosmo.shutdown();
assert.ok(true, 'shutdown() succeeds'); assert.ok(true, 'shutdown() succeeds');
@@ -79,23 +79,23 @@ QUnit.asyncTest('onConnect/onLogout fires', function(assert) {
var numCallbacks = 0; var numCallbacks = 0;
logout(function() { logout(function() {
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onConnect': function() {
assert.ok(true, 'onConnect fired'); cosmo.addEventListener('connect', function(e) {
if (++numCallbacks == 2) { assert.ok(true, 'onConnect fired');
cosmo.shutdown(); if (++numCallbacks == 2) {
QUnit.start(); cosmo.shutdown();
} QUnit.start();
},
'onLogout': function(login_url) {
assert.ok(true, 'onLogout fired');
if (++numCallbacks == 2) {
cosmo.shutdown();
QUnit.start();
}
} }
}; });
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.addEventListener('logout', function(e) {
assert.ok(true, 'onLogout fired');
if (++numCallbacks == 2) {
cosmo.shutdown();
QUnit.start();
}
});
}); });
}); });
@@ -105,16 +105,15 @@ QUnit.asyncTest('Message round trip', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onMessage': function(e) {
assert.equal(e['subject']['name'], subject, 'subject matches'); cosmo.addEventListener('message', function(e) {
assert.equal(e['message'], message, 'message matches'); assert.equal(e.detail['subject']['name'], subject, 'subject matches');
cosmo.shutdown(); assert.equal(e.detail['message'], message, 'message matches');
QUnit.start(); cosmo.shutdown();
} QUnit.start();
}; });
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.sendMessage(subject, message); cosmo.sendMessage(subject, message);
cosmo.subscribe(subject, -1); cosmo.subscribe(subject, -1);
}); });
@@ -125,16 +124,15 @@ QUnit.asyncTest('Message round trip without channel', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onMessage': function(e) {
assert.equal(e['subject']['name'], subject, 'subject matches'); cosmo.addEventListener('message', function(e) {
assert.equal(e['message'], message, 'message matches'); assert.equal(e.detail['subject']['name'], subject, 'subject matches');
cosmo.shutdown(); assert.equal(e.detail['message'], message, 'message matches');
QUnit.start(); cosmo.shutdown();
} QUnit.start();
}; });
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.channelState_ = Cosmopolite.ChannelState_.OPENING; cosmo.channelState_ = Cosmopolite.ChannelState_.OPENING;
cosmo.sendMessage(subject, message); cosmo.sendMessage(subject, message);
cosmo.subscribe(subject, -1); cosmo.subscribe(subject, -1);
@@ -149,17 +147,15 @@ QUnit.asyncTest('Bulk subscribe', function(assert) {
var messages = 0; var messages = 0;
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onMessage': function(e) {
assert.equal(e['message'], message, 'message matches');
if (++messages == 2) {
cosmo.shutdown();
QUnit.start();
}
}
};
var cosmo = new Cosmopolite(callbacks, null, randstring()); cosmo.addEventListener('message', function(e) {
assert.equal(e.detail['message'], message, 'message matches');
if (++messages == 2) {
cosmo.shutdown();
QUnit.start();
}
});
cosmo.sendMessage(subject1, message); cosmo.sendMessage(subject1, message);
cosmo.sendMessage(subject2, message); cosmo.sendMessage(subject2, message);
cosmo.subscribe([subject1, subject2], -1); cosmo.subscribe([subject1, subject2], -1);
@@ -180,16 +176,15 @@ QUnit.asyncTest('Complex object', function(assert) {
'unicode': '☠☣☃𠜎' 'unicode': '☠☣☃𠜎'
}; };
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onMessage': function(e) {
assert.equal(e['subject']['name'], subject, 'subject matches'); cosmo.addEventListener('message', function(e) {
assert.deepEqual(e['message'], message, 'message matches'); assert.equal(e.detail['subject']['name'], subject, 'subject matches');
cosmo.shutdown(); assert.deepEqual(e.detail['message'], message, 'message matches');
QUnit.start(); cosmo.shutdown();
} QUnit.start();
}; });
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.sendMessage(subject, message); cosmo.sendMessage(subject, message);
cosmo.subscribe(subject, -1); cosmo.subscribe(subject, -1);
}); });
@@ -200,7 +195,7 @@ QUnit.asyncTest('sendMessage Promise', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
cosmo.sendMessage(subject, message).then(function(msg) { cosmo.sendMessage(subject, message).then(function(msg) {
assert.ok(true, 'sendMessage Promise fulfilled'); assert.ok(true, 'sendMessage Promise fulfilled');
assert.equal(msg['subject']['name'], subject); assert.equal(msg['subject']['name'], subject);
@@ -216,7 +211,7 @@ QUnit.asyncTest('subscribe/unsubscribe Promise', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
cosmo.subscribe(subject).then(function() { cosmo.subscribe(subject).then(function() {
assert.ok(true, 'subscribe Promise fulfilled'); assert.ok(true, 'subscribe Promise fulfilled');
cosmo.unsubscribe(subject).then(function() { cosmo.unsubscribe(subject).then(function() {
@@ -234,22 +229,22 @@ QUnit.asyncTest('Duplicate message suppression', function(assert) {
var message1 = randstring(); var message1 = randstring();
var message2 = randstring(); var message2 = randstring();
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onMessage': function(msg) {
assert.equal(msg['subject']['name'], subject, 'subject matches');
assert.equal(msg['message'], message1, 'message matches');
cosmo.shutdown();
QUnit.start();
}
};
var cosmo = new Cosmopolite(callbacks, null, randstring());
// Break cosmo's UUID generator so that it generates duplicate values. // Break cosmo's UUID generator so that it generates duplicate values.
cosmo.uuid_ = function() { cosmo.uuid_ = function() {
return '4'; return '4';
// chosen by fair dice roll. // chosen by fair dice roll.
// guaranteed to be random. // guaranteed to be random.
}; };
cosmo.addEventListener('message', function(e) {
assert.equal(e.detail['subject']['name'], subject, 'subject matches');
assert.equal(e.detail['message'], message1, 'message matches');
cosmo.shutdown();
QUnit.start();
});
cosmo.sendMessage(subject, message1).then(function() { cosmo.sendMessage(subject, message1).then(function() {
cosmo.sendMessage(subject, message2).then(function() { cosmo.sendMessage(subject, message2).then(function() {
cosmo.subscribe(subject, -1); cosmo.subscribe(subject, -1);
@@ -265,20 +260,19 @@ QUnit.asyncTest('Message persistence', function(assert) {
var namespace = randstring(); var namespace = randstring();
// Send a message and shut down too fast for it to hit the wire. // Send a message and shut down too fast for it to hit the wire.
var cosmo1 = new Cosmopolite({}, null, namespace); var cosmo1 = new Cosmopolite(null, namespace);
cosmo1.sendMessage(subject, message); cosmo1.sendMessage(subject, message);
cosmo1.shutdown(); cosmo1.shutdown();
var callbacks = { var cosmo2 = new Cosmopolite(null, namespace);
'onMessage': function(msg) {
assert.equal(msg['subject']['name'], subject, 'subject matches'); cosmo2.addEventListener('message', function(e) {
assert.equal(msg['message'], message, 'message matches'); assert.equal(e.detail['subject']['name'], subject, 'subject matches');
cosmo2.shutdown(); assert.equal(e.detail['message'], message, 'message matches');
QUnit.start(); cosmo2.shutdown();
} QUnit.start();
}; });
var cosmo2 = new Cosmopolite(callbacks, null, namespace);
cosmo2.subscribe(subject, -1); cosmo2.subscribe(subject, -1);
// Should pick up the message from the persistent queue. // Should pick up the message from the persistent queue.
}); });
@@ -288,7 +282,7 @@ QUnit.test('getMessages/subscribe', function(assert) {
var subject = randstring(); var subject = randstring();
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
assert.throws( assert.throws(
cosmo.getMessages.bind(undefined, subject), cosmo.getMessages.bind(undefined, subject),
'getMessages before subscribe fails'); 'getMessages before subscribe fails');
@@ -306,7 +300,7 @@ QUnit.asyncTest('subscribe barrier', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
cosmo.sendMessage(subject, message).then(function() { cosmo.sendMessage(subject, message).then(function() {
cosmo.subscribe(subject, -1).then(function() { cosmo.subscribe(subject, -1).then(function() {
@@ -331,7 +325,7 @@ QUnit.asyncTest('resubscribe', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
cosmo.sendMessage(subject, message).then(function() { cosmo.sendMessage(subject, message).then(function() {
cosmo.subscribe(subject).then(function() { cosmo.subscribe(subject).then(function() {
@@ -355,7 +349,7 @@ QUnit.asyncTest('Message ordering', function(assert) {
var subject = randstring(); var subject = randstring();
var messages = ['A', 'B', 'C', 'D']; var messages = ['A', 'B', 'C', 'D'];
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
var sendNextMessage = function() { var sendNextMessage = function() {
if (messages.length) { if (messages.length) {
@@ -383,22 +377,23 @@ QUnit.asyncTest('Reconnect channel', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onConnect': function() {
assert.ok(true, 'onConnect fired'); cosmo.addEventListener('connect', function(e) {
}, assert.ok(true, 'onConnect fired');
'onDisconnect': function() { });
assert.ok(true, 'onDisconnect fired');
}, cosmo.addEventListener('disconnect', function(e) {
'onMessage': function(msg) { assert.ok(true, 'onDisconnect fired');
assert.equal(msg['subject']['name'], subject, 'subject matches'); });
assert.equal(msg['message'], message, 'message matches');
cosmo.shutdown(); cosmo.addEventListener('message', function(e) {
QUnit.start(); assert.equal(e.detail['subject']['name'], subject, 'subject matches');
} assert.equal(e.detail['message'], message, 'message matches');
}; cosmo.shutdown();
QUnit.start();
});
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.subscribe(subject, 0).then(function() { cosmo.subscribe(subject, 0).then(function() {
// Reach inside to forcefully close the socket // Reach inside to forcefully close the socket
cosmo.socket_.close(); cosmo.socket_.close();
@@ -412,11 +407,11 @@ QUnit.asyncTest('subscribe ACL', function(assert) {
var subject = randstring(); var subject = randstring();
logout(function() { logout(function() {
var tempCosmo = new Cosmopolite({}, null, randstring()); var tempCosmo = new Cosmopolite(null, randstring());
tempCosmo.getProfile().then(function(tempProfile) { tempCosmo.getProfile().then(function(tempProfile) {
tempCosmo.shutdown(); tempCosmo.shutdown();
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
cosmo.getProfile().then(function(profile) { cosmo.getProfile().then(function(profile) {
cosmo.subscribe({ cosmo.subscribe({
'name': subject, 'name': subject,
@@ -446,11 +441,11 @@ QUnit.asyncTest('sendMessage ACL', function(assert) {
var message = randstring(); var message = randstring();
logout(function() { logout(function() {
var tempCosmo = new Cosmopolite({}, null, randstring()); var tempCosmo = new Cosmopolite(null, randstring());
tempCosmo.getProfile().then(function(tempProfile) { tempCosmo.getProfile().then(function(tempProfile) {
tempCosmo.shutdown(); tempCosmo.shutdown();
var cosmo = new Cosmopolite({}, null, randstring()); var cosmo = new Cosmopolite(null, randstring());
cosmo.getProfile().then(function(profile) { cosmo.getProfile().then(function(profile) {
cosmo.sendMessage({ cosmo.sendMessage({
'name': subject, 'name': subject,
@@ -483,22 +478,23 @@ QUnit.asyncTest('"me" ACL', function(assert) {
}; };
var message = randstring(); var message = randstring();
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onMessage': function(e) {
assert.equal(e['subject']['name'], subject['name'], 'subject matches'); cosmo.addEventListener('message', function(e) {
assert.equal(e['subject']['readable_only_by'], 'me', assert.equal(e.detail['subject']['name'], subject['name'],
'readable_only_by matches'); 'subject matches');
assert.equal(e['subject']['writable_only_by'], 'me', assert.equal(e.detail['subject']['readable_only_by'], 'me',
'writable_only_by matches'); 'readable_only_by matches');
assert.equal(e['message'], message, 'message matches'); assert.equal(e.detail['subject']['writable_only_by'], 'me',
cosmo.shutdown(); 'writable_only_by matches');
QUnit.start(); assert.equal(e.detail['message'], message, 'message matches');
} cosmo.shutdown();
}; QUnit.start();
});
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.sendMessage(subject, message).then(function(msg) { cosmo.sendMessage(subject, message).then(function(msg) {
assert.equal(msg['subject']['name'], subject['name'], 'subject matches'); assert.equal(msg['subject']['name'], subject['name'],
'subject matches');
assert.equal(msg['subject']['readable_only_by'], 'me', assert.equal(msg['subject']['readable_only_by'], 'me',
'readable_only_by matches'); 'readable_only_by matches');
assert.equal(msg['subject']['writable_only_by'], 'me', assert.equal(msg['subject']['writable_only_by'], 'me',
@@ -513,24 +509,28 @@ QUnit.asyncTest('pin/unpin', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onPin': function(e) {
assert.equal(subject, e['subject']['name'], 'onPin: subject matches'); cosmo.addEventListener('pin', function(e) {
assert.equal(message, e['message'], 'onPin: message matches'); assert.equal(subject, e.detail['subject']['name'],
assert.equal(cosmo.getPins(subject).length, 1); 'onPin: subject matches');
pin.then(function(id) { assert.equal(message, e.detail['message'],
cosmo.unpin(id); 'onPin: message matches');
}); assert.equal(cosmo.getPins(subject).length, 1);
}, pin.then(function(id) {
'onUnpin': function(e) { cosmo.unpin(id);
assert.equal(subject, e['subject']['name'], 'onUnpin: subject matches'); });
assert.equal(message, e['message'], 'onUnpin: message matches'); });
cosmo.shutdown();
QUnit.start(); cosmo.addEventListener('unpin', function(e) {
} assert.equal(subject, e.detail['subject']['name'],
}; 'onUnpin: subject matches');
assert.equal(message, e.detail['message'],
'onUnpin: message matches');
cosmo.shutdown();
QUnit.start();
});
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.subscribe(subject); cosmo.subscribe(subject);
var pin = cosmo.pin(subject, message); var pin = cosmo.pin(subject, message);
}); });
@@ -543,25 +543,29 @@ QUnit.asyncTest('Repin', function(assert) {
var pins = 0; var pins = 0;
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onPin': function(e) {
assert.equal(subject, e['subject']['name'], 'onPin: subject matches'); cosmo.addEventListener('pin', function(e) {
assert.equal(message, e['message'], 'onPin: message matches'); assert.equal(subject, e.detail['subject']['name'],
assert.equal(cosmo.getPins(subject).length, 1); 'onPin: subject matches');
if (++pins == 1) { assert.equal(message, e.detail['message'],
cosmo.socket_.close(); 'onPin: message matches');
} else { assert.equal(cosmo.getPins(subject).length, 1);
cosmo.shutdown(); if (++pins == 1) {
QUnit.start(); cosmo.socket_.close();
} } else {
}, cosmo.shutdown();
'onUnpin': function(e) { QUnit.start();
assert.equal(subject, e['subject']['name'], 'onUnpin: subject matches'); }
assert.equal(message, e['message'], 'onUnpin: message matches'); });
}
}; cosmo.addEventListener('unpin', function(e) {
assert.equal(subject, e.detail['subject']['name'],
'onUnpin: subject matches');
assert.equal(message, e.detail['message'],
'onUnpin: message matches');
});
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.subscribe(subject); cosmo.subscribe(subject);
var pin = cosmo.pin(subject, message); var pin = cosmo.pin(subject, message);
}); });
@@ -575,27 +579,26 @@ QUnit.asyncTest('Duplicate subject', function(assert) {
var messages = 0; var messages = 0;
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onConnect': function() {
cosmo.sendMessage(subject, message1);
cosmo.sendMessage(subject, message2);
cosmo.subscribe(subject, -1);
},
'onMessage': function(e) {
assert.equal(subject, e['subject']['name'], 'subject matches');
if (e['message'] == message1) {
assert.equal(message1, e['message'], 'message1 matches');
} else {
assert.equal(message2, e['message'], 'message2 matches');
}
if (++messages == 2) {
cosmo.shutdown();
QUnit.start();
}
}
};
var cosmo = new Cosmopolite(callbacks, null, randstring()); cosmo.addEventListener('connect', function(e) {
cosmo.sendMessage(subject, message1);
cosmo.sendMessage(subject, message2);
cosmo.subscribe(subject, -1);
});
cosmo.addEventListener('message', function(e) {
assert.equal(subject, e.detail['subject']['name'], 'subject matches');
if (e.detail['message'] == message1) {
assert.equal(message1, e.detail['message'], 'message1 matches');
} else {
assert.equal(message2, e.detail['message'], 'message2 matches');
}
if (++messages == 2) {
cosmo.shutdown();
QUnit.start();
}
});
}); });
@@ -607,25 +610,25 @@ QUnit.asyncTest('Login', function(assert) {
var anonymousProfile; var anonymousProfile;
logout(function() { logout(function() {
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onLogout': function(login_url) {
assert.ok(true, 'onLogout fired'); cosmo.addEventListener('login', function(e) {
anonymousProfile = cosmo.currentProfile(); assert.ok(true, 'onLogin fired');
// Entirely magic URL that sets the login cookie and redirects. assert.notEqual(anonymousProfile, cosmo.currentProfile(),
window.open( 'profile changed');
'/_ah/login?email=test%40example.com&action=Login' + cosmo.shutdown();
'&continue=/cosmopolite/static/login_complete.html'); logout();
}, QUnit.start();
'onLogin': function(login_url) { });
assert.ok(true, 'onLogin fired');
assert.notEqual(anonymousProfile, cosmo.currentProfile(), cosmo.addEventListener('logout', function(e) {
'profile changed'); assert.ok(true, 'onLogout fired');
cosmo.shutdown(); anonymousProfile = cosmo.currentProfile();
logout(); // Entirely magic URL that sets the login cookie and redirects.
QUnit.start(); window.open(
} '/_ah/login?email=test%40example.com&action=Login' +
}; '&continue=/cosmopolite/static/login_complete.html');
var cosmo = new Cosmopolite(callbacks, null, randstring()); });
}); });
}); });
@@ -638,32 +641,33 @@ QUnit.asyncTest('Profile merge', function(assert) {
var messages = 0; var messages = 0;
logout(function() { logout(function() {
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onMessage': function(msg) {
messages++; cosmo.addEventListener('login', function(e) {
assert.equal(msg['subject']['name'], subject, cosmo.subscribe(subject, -1);
'message #' + messages + ': subject matches'); });
assert.equal(msg['message'], message,
'message #' + messages + ': message matches'); cosmo.addEventListener('message', function(e) {
assert.equal(msg['sender'], cosmo.currentProfile(), messages++;
'message #' + messages + ': profile matches'); assert.equal(e.detail['subject']['name'], subject,
if (messages == 1) { 'message #' + messages + ': subject matches');
cosmo.unsubscribe(subject); assert.equal(e.detail['message'], message,
// Entirely magic URL that sets the login cookie and redirects. 'message #' + messages + ': message matches');
window.open( assert.equal(e.detail['sender'], cosmo.currentProfile(),
'/_ah/login?email=test%40example.com&action=Login' + 'message #' + messages + ': profile matches');
'&continue=/cosmopolite/static/login_complete.html'); if (messages == 1) {
} cosmo.unsubscribe(subject);
if (messages == 2) { // Entirely magic URL that sets the login cookie and redirects.
cosmo.shutdown(); window.open(
QUnit.start(); '/_ah/login?email=test%40example.com&action=Login' +
} '&continue=/cosmopolite/static/login_complete.html');
},
'onLogin': function(logout_url) {
cosmo.subscribe(subject, -1);
} }
}; if (messages == 2) {
var cosmo = new Cosmopolite(callbacks, null, randstring()); cosmo.shutdown();
QUnit.start();
}
});
cosmo.sendMessage(subject, message); cosmo.sendMessage(subject, message);
cosmo.subscribe(subject, -1); cosmo.subscribe(subject, -1);
}); });
@@ -676,18 +680,17 @@ QUnit.asyncTest('Two channels, one client', function(assert) {
var subject = randstring(); var subject = randstring();
var message = randstring(); var message = randstring();
var callbacks = { var cosmo1 = new Cosmopolite(null, namespace);
'onMessage': function(msg) {
assert.equal(msg['subject']['name'], subject, 'subject matches'); cosmo1.addEventListener('message', function(e) {
assert.equal(msg['message'], message, 'message matches'); assert.equal(e.detail['subject']['name'], subject, 'subject matches');
cosmo1.shutdown(); assert.equal(e.detail['message'], message, 'message matches');
QUnit.start(); cosmo1.shutdown();
} QUnit.start();
}; });
var cosmo1 = new Cosmopolite(callbacks, null, namespace);
cosmo1.subscribe(subject).then(function() { cosmo1.subscribe(subject).then(function() {
var cosmo2 = new Cosmopolite({}, null, namespace); var cosmo2 = new Cosmopolite(null, namespace);
cosmo2.sendMessage(subject, message).then(function() { cosmo2.sendMessage(subject, message).then(function() {
cosmo2.shutdown(); cosmo2.shutdown();
}); });
@@ -700,20 +703,20 @@ QUnit.asyncTest('subscribe admin ACL', function(assert) {
var subject = randstring(); var subject = randstring();
logout(function() { logout(function() {
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onLogin': function() {
cosmo.subscribe({ cosmo.addEventListener('login', function(e) {
'name': subject, cosmo.subscribe({
'readable_only_by': 'admin' 'name': subject,
}).then(function() { 'readable_only_by': 'admin'
assert.ok(true, 'logged in succeeds'); }).then(function() {
assert.ok(true, 'logged in succeeds');
cosmo.shutdown();
QUnit.start();
});
});
cosmo.shutdown();
QUnit.start();
});
}
};
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.subscribe({ cosmo.subscribe({
'name': subject, 'name': subject,
'readable_only_by': 'admin' 'readable_only_by': 'admin'
@@ -734,20 +737,20 @@ QUnit.asyncTest('sendMessage admin ACL', function(assert) {
var message = randstring(); var message = randstring();
logout(function() { logout(function() {
var callbacks = { var cosmo = new Cosmopolite(null, randstring());
'onLogin': function() {
cosmo.sendMessage({ cosmo.addEventListener('login', function(e) {
'name': subject, cosmo.sendMessage({
'writable_only_by': 'admin' 'name': subject,
}, message).then(function() { 'writable_only_by': 'admin'
assert.ok(true, 'logged in succeeds'); }, message).then(function() {
assert.ok(true, 'logged in succeeds');
cosmo.shutdown();
QUnit.start();
});
});
cosmo.shutdown();
QUnit.start();
});
}
};
var cosmo = new Cosmopolite(callbacks, null, randstring());
cosmo.sendMessage({ cosmo.sendMessage({
'name': subject, 'name': subject,
'writable_only_by': 'admin' 'writable_only_by': 'admin'