postal.js/spec/Postal.spec.js
2012-03-01 03:40:47 -05:00

546 lines
No EOL
27 KiB
JavaScript

QUnit.specify("postal.js", function(){
describe("Postal", function(){
var subscription,
sub,
channel,
caughtSubscribeEvent = false,
caughtUnsubscribeEvent = false;
describe("when creating basic subscription", function() {
var systemSubscription = {};
before(function(){
systemSubscription = postal.subscribe({
exchange: "postal",
topic: "subscription.created",
callback: function(x){
console.log("on subscription " + JSON.stringify(x));
if( x.event &&
x.event == "subscription.created" &&
x.exchange == "MyExchange" &&
x.topic == "MyTopic") {
caughtSubscribeEvent = true;
};
}
});
subscription = postal.channel({ exchange: "MyExchange", topic: "MyTopic" })
.subscribe(function() { });
sub = postal.configuration.bus.subscriptions.MyExchange.MyTopic[0];
});
after(function(){
systemSubscription.unsubscribe();
postal.configuration.bus.subscriptions = {};
});
it("should create an exchange called MyExchange", function(){
assert(postal.configuration.bus.subscriptions["MyExchange"] !== undefined).isTrue();
});
it("should create a topic under MyExchange called MyTopic", function(){
assert(postal.configuration.bus.subscriptions["MyExchange"]["MyTopic"] !== undefined).isTrue();
});
it("should have set subscription exchange value", function() {
assert(sub.exchange).equals("MyExchange");
});
it("should have set subscription topic value", function() {
assert(sub.topic).equals("MyTopic");
});
it("should have set subscription priority value", function() {
assert(sub.priority).equals(50);
});
it("should have defaulted the subscription constraints array", function() {
assert(sub.constraints.length).equals(0);
});
it("should have defaulted the subscription disposeAfter value", function() {
assert(sub.maxCalls).equals(0);
});
it("should have defaulted the subscription context value", function() {
assert(sub.context).isNull();
});
it("should have captured subscription creation event in wire-tap", function() {
assert(caughtSubscribeEvent).isTrue();
});
});
describe("when unsubscribing", function() {
var subExistsBefore = false,
subExistsAfter = true;
var systemSubscription = {};
before(function(){
systemSubscription = postal.subscribe({
exchange: "postal",
topic: "subscription.*",
callback: function(x){
console.log("on unsubscription " + JSON.stringify(x));
if( x.event &&
x.event == "subscription.removed" &&
x.exchange == "MyExchange" &&
x.topic == "MyTopic") {
caughtUnsubscribeEvent = true;
};
}
});
subscription = postal.channel({ exchange: "MyExchange", topic: "MyTopic" })
.subscribe(function() { });
subExistsBefore = postal.configuration.bus.subscriptions.MyExchange.MyTopic[0] !== undefined;
subscription.unsubscribe();
subExistsAfter = postal.configuration.bus.subscriptions.MyExchange.MyTopic.length !== 0;
});
after(function(){
systemSubscription.unsubscribe();
postal.configuration.bus.subscriptions = {};
});
it("subscription should exist before unsubscribe", function(){
assert(subExistsBefore).isTrue();
});
it("subscription should not exist after unsubscribe", function(){
assert(subExistsAfter).isFalse();
});
it("should have captured unsubscription creation event in wire-tap", function() {
assert(caughtUnsubscribeEvent).isTrue();
});
});
describe("When publishing a message", function(){
var msgReceivedCnt = 0,
msgData;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" })
subscription = channel.subscribe(function(data) { msgReceivedCnt++; msgData = data;});
channel.publish("Testing123");
subscription.unsubscribe();
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("subscription callback should be invoked once", function(){
assert(msgReceivedCnt).equals(1);
});
it("subscription callback should receive published data", function(){
assert(msgData).equals("Testing123");
});
});
describe("When subscribing with a disposeAfter of 5", function(){
var msgReceivedCnt = 0;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { msgReceivedCnt++; })
.disposeAfter(5);
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("subscription callback should be invoked 5 times", function(){
assert(msgReceivedCnt).equals(5);
});
});
describe("When subscribing and ignoring duplicates", function(){
var subInvokedCnt = 0;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { subInvokedCnt++; })
.ignoreDuplicates();
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
subInvokedCnt = 0;
});
it("should have a constraint on the subscription", function() {
assert(postal.configuration.bus.subscriptions.MyExchange.MyTopic[0].constraints.length).equals(1);
});
it("subscription callback should be invoked once", function(){
assert(subInvokedCnt).equals(1);
});
});
describe("When subscribing and passing onHandled callback", function(){
var whte = false;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { })
.whenHandledThenExecute(function() { whte = true; });
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
whte = false;
});
it("should have an onHandled callback on the subscription", function() {
assert(typeof postal.configuration.bus.subscriptions.MyExchange.MyTopic[0].onHandled).equals("function");
});
it("should have invoked the onHandled callback", function() {
assert(whte).isTrue();
});
});
describe("When subscribing with one constraint returning true", function(){
var recvd = false;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { recvd= true; })
.withConstraint(function() { return true; });
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
recvd = false;
});
it("should have a constraint on the subscription", function() {
assert(postal.configuration.bus.subscriptions.MyExchange.MyTopic[0].constraints.length).equals(1);
});
it("should have invoked the subscription callback", function() {
assert(recvd).isTrue();
});
});
describe("When subscribing with one constraint returning false", function(){
var recvd = false;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { recvd= true; })
.withConstraint(function() { return false; });
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
recvd = false;
});
it("should have a constraint on the subscription", function() {
assert(postal.configuration.bus.subscriptions.MyExchange.MyTopic[0].constraints.length).equals(1);
});
it("should not have invoked the subscription callback", function() {
assert(recvd).isFalse();
});
});
describe("When subscribing with multiple constraints returning true", function(){
var recvd = false;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { recvd= true; })
.withConstraints([function() { return true; },
function() { return true; },
function() { return true; }]);
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
recvd = false;
});
it("should have a constraint on the subscription", function() {
assert(postal.configuration.bus.subscriptions.MyExchange.MyTopic[0].constraints.length).equals(3);
});
it("should have invoked the onHandled callback", function() {
assert(recvd).isTrue();
});
});
describe("When subscribing with multiple constraints and one returning false", function(){
var recvd = false;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { recvd= true; })
.withConstraints([function() { return true; },
function() { return false; },
function() { return true; }]);
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
recvd = false;
});
it("should have a constraint on the subscription", function() {
assert(postal.configuration.bus.subscriptions.MyExchange.MyTopic[0].constraints.length).equals(3);
});
it("should not have invoked the onHandled callback", function() {
assert(recvd).isFalse();
});
});
describe("When subscribing with the context being set", function(){
var count = 0,
obj = {
increment: function() {
count++;
}
};
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { this.increment(); })
.withContext(obj);
channel.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("should have called obj.increment", function() {
assert(count).equals(1);
});
});
describe("When subscribing with a hierarchical binding, no wildcards", function(){
var count = 0, channelB, channelC;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic" });
channelB = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic" });
channelC = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic.YetAnother" });
subscription = channel.subscribe(function(data) { count++; });
channel.publish("Testing123");
channelB.publish("Testing123");
channelC.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
count = 0;
});
it("should have invoked subscription callback only once", function() {
assert(count).equals(1);
});
});
describe("When subscribing with a hierarchical binding, using #", function(){
var count = 0, channelB, channelC, channelD;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic.#.SubTopic" });
channelB = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic" });
channelC = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic" });
channelD = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic.YetAnother" });
subscription = channel.subscribe(function(data) { count++; });
channelC.publish({exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic", data: "Testing123"});
channelB.publish({exchange: "MyExchange", topic: "MyTopic.MiddleTopic", data: "Testing123"});
channelD.publish({exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic.YetAnother", data: "Testing123"});
});
after(function(){
postal.configuration.bus.subscriptions = {};
count = 0;
});
it("should have invoked subscription callback only once", function() {
assert(count).equals(1);
});
});
describe("When subscribing with a hierarchical binding, using *", function(){
var count = 0, channelB, channelC, channelD;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.*" });
channelB = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic" });
channelC = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic" });
channelD = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic.YetAnother" });
subscription = channel.subscribe(function(data) { count++; });
channelC.publish("Testing123");
channelB.publish("Testing123");
channelD.publish("Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
count = 0;
});
it("should have invoked subscription callback twice", function() {
assert(count).equals(2);
});
});
describe("When subscribing with a hierarchical binding, using # and *", function(){
var count = 0, channelB, channelC, channelD, channelE;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic.#.*" });
channelB = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic" });
channelC = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic" });
channelD = postal.channel({ exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic.YetAnother" });
channelE = postal.channel({ exchange: "MyExchange", topic: "OtherTopic.MiddleTopic.SubTopic.YetAnother" });
subscription = channel.subscribe(function(data) { count++; });
channelC.publish({exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic", data: "Testing123"});
channelB.publish({exchange: "MyExchange", topic: "MyTopic.MiddleTopic", data: "Testing123"});
channelD.publish({exchange: "MyExchange", topic: "MyTopic.MiddleTopic.SubTopic.YetAnother", data: "Testing123"});
channelE.publish({exchange: "MyExchange", topic: "OtherTopic.MiddleTopic.SubTopic.YetAnother", data: "Testing123"});
});
after(function(){
postal.configuration.bus.subscriptions = {};
count = 0;
});
it("should have invoked subscription callback twice", function() {
assert(count).equals(2);
});
});
describe("When using shortcut publish api", function(){
var msgReceivedCnt = 0,
msgData;
before(function(){
channel = postal.channel({ exchange: "MyExchange", topic: "MyTopic" });
subscription = channel.subscribe(function(data) { msgReceivedCnt++; msgData = data;});
postal.publish("MyExchange", "MyTopic", "Testing123");
subscription.unsubscribe();
postal.publish("MyExchange", "MyTopic", "Testing123");
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("subscription callback should be invoked once", function(){
assert(msgReceivedCnt).equals(1);
});
it("subscription callback should receive published data", function(){
assert(msgData).equals("Testing123");
});
});
describe("When using shortcut subscribe api", function(){
before(function(){
subscription = postal.subscribe({
exchange: "MyExchange",
topic: "MyTopic",
callback: function() { }
});
sub = postal.configuration.bus.subscriptions.MyExchange.MyTopic[0];
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("should create an exchange called MyExchange", function(){
assert(postal.configuration.bus.subscriptions["MyExchange"] !== undefined).isTrue();
});
it("should create a topic under MyExchange called MyTopic", function(){
assert(postal.configuration.bus.subscriptions["MyExchange"]["MyTopic"] !== undefined).isTrue();
});
it("should have set subscription exchange value", function() {
assert(sub.exchange).equals("MyExchange");
});
it("should have set subscription topic value", function() {
assert(sub.topic).equals("MyTopic");
});
it("should have set subscription priority value", function() {
assert(sub.priority).equals(50);
});
it("should have defaulted the subscription constraints array", function() {
assert(sub.constraints.length).equals(0);
});
it("should have defaulted the subscription disposeAfter value", function() {
assert(sub.maxCalls).equals(0);
});
it("should have defaulted the subscription context value", function() {
assert(sub.context).isNull();
});
});
describe("when subscribing and unsubscribing a wire tap", function() {
var wireTapData,
wireTapEnvelope,
wiretap;
before(function(){
caughtUnsubscribeEvent = false;
wireTapData = [];
wireTapEnvelope = [];
wiretap = postal.addWireTap(function(envelope, msg) {
wireTapData.push(msg);
wireTapEnvelope.push(envelope);
});
postal.publish({ topic: "Oh.Hai.There" }, { data: "I'm in yer bus, tappin' yer subscriptionz..."});
wiretap();
postal.publish({ topic: "Oh.Hai.There" }, { data: "I'm in yer bus, tappin' yer subscriptionz..."});
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("wire tap should have been invoked only once", function(){
assert(wireTapData.length).equals(1);
assert(wireTapEnvelope.length).equals(1);
});
it("wireTap data should match expected results", function(){
assert(wireTapData[0].data).equals("I'm in yer bus, tappin' yer subscriptionz...");
});
it("wireTap envelope should match expected results", function() {
console.log("ONOES! " + JSON.stringify(wireTapEnvelope));
assert(wireTapEnvelope[0].exchange).equals(DEFAULT_EXCHANGE);
assert(wireTapEnvelope[0].topic).equals("Oh.Hai.There");
});
});
describe("when binding exchange - one source to one destination", function(){
describe("with only exchange values provided", function(){
var destData = [],
destEnv = [],
linkages;
before(function(){
linkages = postal.bindExchanges({ exchange: "sourceExchange" }, { exchange: "destinationExchange" });
subscription = postal.subscribe({ exchange: "destinationExchange", topic: "Oh.Hai.There", callback: function(data, env) {
destData.push(data);
destEnv.push(env);
});
postal.publish("sourceExchange", "Oh.Hai.There", { data: "I'm in yer bus, linkin' to yer subscriptionz..."});
linkages[0].unsubscribe();
postal.publish("sourceExchange", "Oh.Hai.There", { data: "I'm in yer bus, linkin' to yer subscriptionz..."});
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("linked subscription should only have been invoked once", function(){
assert(destData.length).equals(1);
assert(destEnv.length).equals(1);
});
it("linked subscription data should match expected results", function(){
assert(destData[0].data).equals("I'm in yer bus, linkin' to yer subscriptionz...");
});
it("linked subscription envelope should match expected results", function() {
assert(destEnv[0].exchange).equals("destinationExchange");
assert(destEnv[0].topic).equals("Oh.Hai.There");
});
});
describe("with exchange and static topic values provided", function(){
var destData = [],
destEnv = [],
linkages;
before(function(){
linkages = postal.bindExchanges({ exchange: "sourceExchange", topic: "Oh.Hai.There" }, { exchange: "destinationExchange", topic: "kthxbye" });
subscription = postal.subscribe({ exchange: "destinationExchange", topic: "kthxbye", callback: function(data, env) {
destData.push(data);
destEnv.push(env);
});
postal.publish("sourceExchange", "Oh.Hai.There", { data: "I'm in yer bus, linkin' to yer subscriptionz..."});
linkages[0].unsubscribe();
postal.publish("sourceExchange", "Oh.Hai.There", { data: "I'm in yer bus, linkin' to yer subscriptionz..."});
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("linked subscription should only have been invoked once", function(){
assert(destData.length).equals(1);
assert(destEnv.length).equals(1);
});
it("linked subscription data should match expected results", function(){
assert(destData[0].data).equals("I'm in yer bus, linkin' to yer subscriptionz...");
});
it("linked subscription envelope should match expected results", function() {
assert(destEnv[0].exchange).equals("destinationExchange");
assert(destEnv[0].topic).equals("kthxbye");
});
});
describe("with exchange and topic transform values provided", function(){
var destData = [],
destEnv = [],
linkages;
before(function(){
linkages = postal.bindExchanges({ exchange: "sourceExchange" }, { exchange: "destinationExchange", topic: function(tpc) { return "NewTopic." + tpc; } });
subscription = postal.subscribe({ exchange: "destinationExchange", topic: "NewTopic.Oh.Hai.There", callback: function(data, env) {
destData.push(data);
destEnv.push(env);
});
postal.publish("sourceExchange", "Oh.Hai.There", { data: "I'm in yer bus, linkin' to yer subscriptionz..."});
linkages[0].unsubscribe();
postal.publish("sourceExchange", "Oh.Hai.There", { data: "I'm in yer bus, linkin' to yer subscriptionz..."});
});
after(function(){
postal.configuration.bus.subscriptions = {};
});
it("linked subscription should only have been invoked once", function(){
assert(destData.length).equals(1);
assert(destEnv.length).equals(1);
});
it("linked subscription data should match expected results", function(){
assert(destData[0].data).equals("I'm in yer bus, linkin' to yer subscriptionz...");
});
it("linked subscription envelope should match expected results", function() {
assert(destEnv[0].exchange).equals("destinationExchange");
assert(destEnv[0].topic).equals("NewTopic.Oh.Hai.There");
});
});
});
});
});