diff --git a/example/amd/js/libs/postal/postal.js b/example/amd/js/libs/postal/postal.js index 2a7a0a8..42e37e7 100644 --- a/example/amd/js/libs/postal/postal.js +++ b/example/amd/js/libs/postal/postal.js @@ -174,15 +174,6 @@ SubscriptionDefinition.prototype = { } var fn = this.callback; this.callback = _.debounce(fn, milliseconds); - /*this.callback = (function(){ - var debounced; - return function(data) { - if(!debounced) { - debounced = _.debounce(function() { fn(data); }, milliseconds); - } - debounced(); - }; - })();*/ return this; }, diff --git a/example/standard/js/postal.js b/example/standard/js/postal.js index 2a7a0a8..42e37e7 100644 --- a/example/standard/js/postal.js +++ b/example/standard/js/postal.js @@ -174,15 +174,6 @@ SubscriptionDefinition.prototype = { } var fn = this.callback; this.callback = _.debounce(fn, milliseconds); - /*this.callback = (function(){ - var debounced; - return function(data) { - if(!debounced) { - debounced = _.debounce(function() { fn(data); }, milliseconds); - } - debounced(); - }; - })();*/ return this; }, diff --git a/lib/browser/postal.diagnostics.min.gz.js b/lib/browser/postal.diagnostics.min.gz.js index 88f619a..c5d50e3 100644 Binary files a/lib/browser/postal.diagnostics.min.gz.js and b/lib/browser/postal.diagnostics.min.gz.js differ diff --git a/lib/browser/postal.js b/lib/browser/postal.js index 2a7a0a8..42e37e7 100644 --- a/lib/browser/postal.js +++ b/lib/browser/postal.js @@ -174,15 +174,6 @@ SubscriptionDefinition.prototype = { } var fn = this.callback; this.callback = _.debounce(fn, milliseconds); - /*this.callback = (function(){ - var debounced; - return function(data) { - if(!debounced) { - debounced = _.debounce(function() { fn(data); }, milliseconds); - } - debounced(); - }; - })();*/ return this; }, diff --git a/lib/browser/postal.min.gz.js b/lib/browser/postal.min.gz.js index 6f6525e..283f9c5 100644 Binary files a/lib/browser/postal.min.gz.js and b/lib/browser/postal.min.gz.js differ diff --git a/lib/node/postal.js b/lib/node/postal.js index 2109c64..65c81fb 100644 --- a/lib/node/postal.js +++ b/lib/node/postal.js @@ -164,15 +164,6 @@ SubscriptionDefinition.prototype = { } var fn = this.callback; this.callback = _.debounce(fn, milliseconds); - /*this.callback = (function(){ - var debounced; - return function(data) { - if(!debounced) { - debounced = _.debounce(function() { fn(data); }, milliseconds); - } - debounced(); - }; - })();*/ return this; }, diff --git a/package.json b/package.json index 6fd4a2a..824638e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Jim Cowart (http://ifandelse.com)", "name": "postal", "description": "Pub/Sub library providing wildcard subscriptions, complex message handling, etc. Works server and client-side.", - "version": "0.4.0", + "version": "0.6.0", "homepage": "http://github.com/ifandelse/postal.js", "repository": { "type": "git", diff --git a/spec/ChannelDefinition.spec.js b/spec/ChannelDefinition.spec.js index 15378ab..e4be6b8 100644 --- a/spec/ChannelDefinition.spec.js +++ b/spec/ChannelDefinition.spec.js @@ -16,5 +16,15 @@ QUnit.specify("postal.js", function(){ assert(sub instanceof SubscriptionDefinition).isTrue(); }); }); + describe("When calling topic", function() { + var ch = new ChannelDefinition("TestChannel", "TestTopic"), + ch2 = ch.topic("TestTopic2"); + it("new channel should be of type ChannelDefinition", function(){ + assert(ch2 instanceof ChannelDefinition).isTrue(); + }); + it("new channel should have topic of TestTopic2", function(){ + assert(ch2._topic).equals("TestTopic2"); + }); + }); }); }); \ No newline at end of file diff --git a/spec/Postal.spec.js b/spec/Postal.spec.js index 75db4c2..b201bdf 100644 --- a/spec/Postal.spec.js +++ b/spec/Postal.spec.js @@ -6,7 +6,7 @@ QUnit.specify("postal.js", function(){ caughtSubscribeEvent = false, caughtUnsubscribeEvent = false; - describe("when creating basic subscription", function() { + describe("When creating basic subscription", function() { var systemSubscription = {}; before(function(){ systemSubscription = postal.subscribe({ @@ -57,7 +57,7 @@ QUnit.specify("postal.js", function(){ assert(caughtSubscribeEvent).isTrue(); }); }); - describe("when unsubscribing", function() { + describe("When unsubscribing", function() { var subExistsBefore = false, subExistsAfter = true; var systemSubscription = {}; @@ -270,7 +270,7 @@ QUnit.specify("postal.js", function(){ it("should have met expected results", function() { channel.publish("Testing123"); results.push("first"); - wait(500, function(){ + wait(1, function(){ assert(results[0]).equals("first"); assert(results[1]).equals("second"); }); @@ -340,7 +340,6 @@ QUnit.specify("postal.js", function(){ }, 1500); })); }); - describe("When subscribing with a hierarchical binding, no wildcards", function(){ var count = 0, channelB, channelC; before(function(){ @@ -424,18 +423,22 @@ QUnit.specify("postal.js", function(){ assert(count).equals(2); }); }); - describe("When using shortcut publish api", function(){ + describe("When using global publish api", function(){ var msgReceivedCnt = 0, msgData; before(function(){ - channel = postal.channel({ channel: "MyChannel", topic: "MyTopic" }); + channel = postal.channel({ channel: "MyGlobalChannel", topic: "MyTopic" }); subscription = channel.subscribe(function(data) { msgReceivedCnt++; msgData = data;}); - postal.publish("MyChannel", "MyTopic", "Testing123"); + postal.publish("MyGlobalChannel", "MyTopic", "Testing123"); subscription.unsubscribe(); - postal.publish("MyChannel", "MyTopic", "Testing123"); + postal.publish("MyGlobalChannel", "MyTopic", "Testing123"); }); after(function(){ postal.reset(); + msgReceivedCnt = 0; + }); + it("channel should be of type ChannelDefinition", function(){ + assert(channel instanceof ChannelDefinition).isTrue(); }); it("subscription callback should be invoked once", function(){ assert(msgReceivedCnt).equals(1); @@ -444,7 +447,7 @@ QUnit.specify("postal.js", function(){ assert(msgData).equals("Testing123"); }); }); - describe("When using shortcut subscribe api", function(){ + describe("When using global subscribe api", function(){ before(function(){ subscription = postal.subscribe({ channel: "MyChannel", @@ -456,6 +459,9 @@ QUnit.specify("postal.js", function(){ after(function(){ postal.reset(); }); + it("subscription should be of type SubscriptionDefinition", function(){ + assert(subscription instanceof SubscriptionDefinition).isTrue(); + }); it("should create an channel called MyChannel", function(){ assert(postal.configuration.bus.subscriptions["MyChannel"] !== undefined).isTrue(); }); @@ -481,7 +487,82 @@ QUnit.specify("postal.js", function(){ assert(sub.context).isNull(); }); }); - describe("when subscribing and unsubscribing a wire tap", function() { + describe("When using global channel api", function(){ + var gch; + describe("With no channel name provided", function(){ + describe("Using string argument", function(){ + before(function(){ + gch = postal.channel("SomeTopic"); + }); + after(function(){ + gch = undefined; + }); + it("channel should be of type ChannelDefinition", function(){ + assert(gch instanceof ChannelDefinition).isTrue(); + }); + it("should set channel name to DEFAULT_CHANNEL", function(){ + assert(gch.channel).equals(DEFAULT_CHANNEL); + }); + it("should set topic to SomeTopic", function(){ + assert(gch._topic).equals("SomeTopic"); + }); + }); + describe("Using options (object) argument", function(){ + before(function(){ + gch = postal.channel({ topic: "SomeTopic" }); + }); + after(function(){ + gch = undefined; + }); + it("channel should be of type ChannelDefinition", function(){ + assert(gch instanceof ChannelDefinition).isTrue(); + }); + it("should set channel name to DEFAULT_CHANNEL", function(){ + assert(gch.channel).equals(DEFAULT_CHANNEL); + }); + it("should set topic to SomeTopic", function(){ + assert(gch._topic).equals("SomeTopic"); + }); + }); + }); + describe("With channel name provided", function(){ + describe("Using string arguments", function() { + before(function(){ + gch = postal.channel("SomeChannel", "SomeTopic"); + }); + after(function(){ + gch = undefined; + }); + it("channel should be of type ChannelDefinition", function(){ + assert(gch instanceof ChannelDefinition).isTrue(); + }); + it("should set channel name to SomeChannel", function(){ + assert(gch.channel).equals("SomeChannel"); + }); + it("should set topic to SomeTopic", function(){ + assert(gch._topic).equals("SomeTopic"); + }); + }); + describe("Using options (object) argument", function() { + before(function(){ + gch = postal.channel({ channel: "SomeChannel", topic: "SomeTopic" }); + }); + after(function(){ + gch = undefined; + }); + it("channel should be of type ChannelDefinition", function(){ + assert(gch instanceof ChannelDefinition).isTrue(); + }); + it("should set channel name to SomeChannel", function(){ + assert(gch.channel).equals("SomeChannel"); + }); + it("should set topic to SomeTopic", function(){ + assert(gch._topic).equals("SomeTopic"); + }); + }); + }); + }); + describe("When subscribing and unsubscribing a wire tap", function() { var wireTapData, wireTapEnvelope, wiretap; @@ -512,7 +593,7 @@ QUnit.specify("postal.js", function(){ assert(wireTapEnvelope[0].topic).equals("Oh.Hai.There"); }); }); - describe("when binding channel - one source to one destination", function(){ + describe("When binding channel - one source to one destination", function(){ describe("with only channel values provided", function(){ var destData = [], destEnv = [], @@ -601,5 +682,36 @@ QUnit.specify("postal.js", function(){ }); }); }); + describe("When calling postal.reset", function(){ + var resolver; + before(function(){ + postal.reset(); + subscription = postal.channel({ channel: "MyChannel", topic: "MyTopic" }).subscribe(function() { }); + postal.channel({ channel: "MyChannel", topic: "MyTopic" }).publish("Oh Hai!"); + sub = postal.configuration.bus.subscriptions.MyChannel.MyTopic[0]; + resolver = postal.configuration.resolver.cache["MyTopic"]; + postal.reset(); + }); + after(function(){ + }); + it("should have created a subscription definition", function() { + assert(sub.channel).equals("MyChannel"); + assert(sub.topic).equals("MyTopic"); + assert(sub.priority).equals(50); + assert(sub.constraints.length).equals(0); + assert(sub.maxCalls).equals(0); + assert(sub.context).isNull(); + }); + it("should have created a resolver cache entry", function(){ + assert(_.isEmpty(resolver)).isFalse(); + assert(resolver["MyTopic"]).isTrue(); + }); + it("subscriptions cache should now be empty", function() { + assert(_.isEmpty(postal.configuration.bus.subscriptions)).isTrue(); + }); + it("resolver cache should now be empty", function() { + assert(_.isEmpty(postal.configuration.resolver.cache)).isTrue(); + }); + }); }); }); \ No newline at end of file diff --git a/spec/SubscriptionDefinition.spec.js b/spec/SubscriptionDefinition.spec.js index bae664b..e2edfe8 100644 --- a/spec/SubscriptionDefinition.spec.js +++ b/spec/SubscriptionDefinition.spec.js @@ -1,12 +1,34 @@ QUnit.specify("postal.js", function(){ describe("SubscriptionDefinition", function(){ describe("When initializing SubscriptionDefinition", function() { - var sDef = new SubscriptionDefinition("TestChannel", "TestTopic", NO_OP); - it("should set the channel to TestChannel", function() { - assert(sDef.channel).equals("TestChannel"); + var sDef, + caughtSubscribeEvent, + systemSubscription; + before(function() { + systemSubscription = postal.subscribe({ + channel: "postal", + topic: "subscription.created", + callback: function(data, envelope){ + if( data.event && + data.event == "subscription.created" && + data.channel == "SubDefTestChannel" && + data.topic == "SubDefTestTopic") { + caughtSubscribeEvent = true; + } + } + }); + sDef = new SubscriptionDefinition("SubDefTestChannel", "SubDefTestTopic", NO_OP); }); - it("should set the topic to TestTopic", function() { - assert(sDef.topic).equals("TestTopic"); + after(function(){ + sDef.unsubscribe(); + systemSubscription.unsubscribe(); + caughtSubscribeEvent = false; + }); + it("should set the channel to SubDefTestChannel", function() { + assert(sDef.channel).equals("SubDefTestChannel"); + }); + it("should set the topic to SubDefTestTopic", function() { + assert(sDef.topic).equals("SubDefTestTopic"); }); it("should set the callback", function() { assert(sDef.callback).equals(NO_OP); @@ -20,12 +42,15 @@ QUnit.specify("postal.js", function(){ it("should default the maxCalls", function() { assert(sDef.maxCalls).equals(0); }); - it("should default the onHandled", function() { + it("should default the onHandled callback", function() { assert(sDef.onHandled).equals(NO_OP); }); it("should default the context", function() { assert(sDef.context).isNull(); }); + it("should fire the subscription.created message", function() { + assert(caughtSubscribeEvent).equals(true); + }); }); describe("When setting ignoreDuplicates", function(){ @@ -68,5 +93,89 @@ QUnit.specify("postal.js", function(){ assert(sDefe.priority).equals(10); }); }); + + describe("When calling subscribe to set the callback", function(){ + var sDefe = new SubscriptionDefinition("TestChannel", "TestTopic", NO_OP), + fn = function() {}; + sDefe.subscribe(fn); + + it("Should set the callback", function() { + assert(sDefe.callback).equals(fn); + }); + }); + + describe("When deferring the callback", function(){ + var results = [], + sDefe = new SubscriptionDefinition("TestChannel", "TestTopic", function(data) { + results.push(data); + }).defer(); + sDefe.callback("second"); + results.push("first"); + + it("Should defer the callback", function() { + wait(1, function(){ + assert(results[0]).equals("first"); + assert(results[1]).equals("second"); + }); + }); + }); + + describe("When delaying the callback", function(){ + var results = [], + sDefe = new SubscriptionDefinition("TestChannel", "TestTopic", function(data) { + results.push(data); + }).withDelay(200); + sDefe.callback("second"); + results.push("first"); + + it("Should delay the callback", function() { + wait(300, function(){ + assert(results[0]).equals("first"); + assert(results[1]).equals("second"); + }); + }); + }); + + describe("When debouncing the callback", function(){ + var results = [], + sDefe = new SubscriptionDefinition("TestChannel", "TestTopic", function(data) { + results.push(data); + }).withDebounce(800); + + it("should have only invoked debounced callback once", async(function() { + sDefe.callback(1); // starts the two second clock on debounce + setTimeout(function() { sDefe.callback(2); }, 20); // should not invoke callback + setTimeout(function() { sDefe.callback(3); }, 80); // should not invoke callback + setTimeout(function() { sDefe.callback(4); }, 250); // should not invoke callback + setTimeout(function() { sDefe.callback(5); }, 500); // should not invoke callback + setTimeout(function() { sDefe.callback(6); }, 1000); // should invoke callback + setTimeout(function() { + assert(results[0]).equals(6); + assert(results.length).equals(1); + resume(); + }, 2400); + })); + }); + + describe("When throttling the callback", function(){ + var results = [], + sDefe = new SubscriptionDefinition("TestChannel", "TestTopic", function(data) { + results.push(data); + }).withThrottle(500); + + it("should have only invoked throttled callback twice", async(function() { + sDefe.callback(1); // starts the two second clock on debounce + setTimeout(function() { sDefe.callback(800); }, 800); // should invoke callback + for(var i = 0; i < 20; i++) { + (function(x) { sDefe.callback(x); })(i); + } + setTimeout(function() { + assert(results[0]).equals(1); + assert(results[1]).equals(800); + assert(results.length).equals(2); + resume(); + }, 1500); + })); + }); }); }); diff --git a/spec/runner.html b/spec/runner.html index 83c1e58..faf968a 100644 --- a/spec/runner.html +++ b/spec/runner.html @@ -19,6 +19,7 @@ + diff --git a/src/main/SubscriptionDefinition.js b/src/main/SubscriptionDefinition.js index add69fd..449e060 100644 --- a/src/main/SubscriptionDefinition.js +++ b/src/main/SubscriptionDefinition.js @@ -94,15 +94,6 @@ SubscriptionDefinition.prototype = { } var fn = this.callback; this.callback = _.debounce(fn, milliseconds); - /*this.callback = (function(){ - var debounced; - return function(data) { - if(!debounced) { - debounced = _.debounce(function() { fn(data); }, milliseconds); - } - debounced(); - }; - })();*/ return this; },