From dfde7b48d6a2c80e8ef149da4134fac4327fe374 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Fri, 6 Sep 2013 20:50:57 +0200 Subject: [PATCH 1/3] Ensuring context set for delayed callbacks - also, fixing standalone test runner --- spec/SubscriptionDefinition.spec.js | 22 ++++++++++++++++++++++ spec/index.html | 10 +++++----- src/SubscriptionDefinition.js | 6 ++++-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/spec/SubscriptionDefinition.spec.js b/spec/SubscriptionDefinition.spec.js index 35d58d5..bbb1d21 100644 --- a/spec/SubscriptionDefinition.spec.js +++ b/spec/SubscriptionDefinition.spec.js @@ -119,6 +119,17 @@ describe( "SubscriptionDefinition", function () { sDefe.callback( "second", { topic : "TestTopic" } ); results.push( "first" ); } ); + + it( "Should keep the context intact", function ( done ) { + var context = { + key: 1234 + }; + sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { + expect( this ).to.be( context ); + done(); + } ).withContext(context).defer(); + sDefe.callback( "stuff", { topic : "TestTopic" } ); + } ); } ); describe( "When delaying the callback", function () { @@ -135,6 +146,17 @@ describe( "SubscriptionDefinition", function () { sDefe.callback( "second", { topic : "TestTopic" } ); results.push( "first" ); } ); + + it( "Should keep the context intact", function ( done ) { + var context = { + key: 1234 + }; + sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { + expect( this ).to.be( context ); + done(); + } ).withContext(context).withDelay( 200 ); + sDefe.callback( "stuff", { topic : "TestTopic" } ); + } ); } ); describe( "When debouncing the callback", function () { diff --git a/spec/index.html b/spec/index.html index dbd73fb..4d74a45 100644 --- a/spec/index.html +++ b/spec/index.html @@ -1,14 +1,14 @@ - +
- - - - + + + + diff --git a/src/SubscriptionDefinition.js b/src/SubscriptionDefinition.js index c4d4c69..ddb78f8 100644 --- a/src/SubscriptionDefinition.js +++ b/src/SubscriptionDefinition.js @@ -37,9 +37,10 @@ SubscriptionDefinition.prototype = { defer : function () { var fn = this.callback; + var context = this.context; this.callback = function ( data, env ) { setTimeout( function () { - fn( data, env ); + fn.call( context, data, env ); }, 0 ); }; return this; @@ -113,9 +114,10 @@ SubscriptionDefinition.prototype = { throw "Milliseconds must be a number"; } var fn = this.callback; + var context = this.context; this.callback = function ( data, env ) { setTimeout( function () { - fn( data, env ); + fn.call( context, data, env ); }, milliseconds ); }; return this; From ac3e7ea7d0c5594d895ec90e07ad6aadfb9d3610 Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Fri, 6 Sep 2013 21:21:16 +0200 Subject: [PATCH 2/3] Added context tests for limited callbacks - properly running the delayed context tests - formatting --- spec/SubscriptionDefinition.spec.js | 35 +++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/spec/SubscriptionDefinition.spec.js b/spec/SubscriptionDefinition.spec.js index bbb1d21..45916a3 100644 --- a/spec/SubscriptionDefinition.spec.js +++ b/spec/SubscriptionDefinition.spec.js @@ -122,13 +122,13 @@ describe( "SubscriptionDefinition", function () { it( "Should keep the context intact", function ( done ) { var context = { - key: 1234 + key : 1234 }; sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { expect( this ).to.be( context ); done(); } ).withContext(context).defer(); - sDefe.callback( "stuff", { topic : "TestTopic" } ); + sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } ); } ); } ); @@ -149,13 +149,13 @@ describe( "SubscriptionDefinition", function () { it( "Should keep the context intact", function ( done ) { var context = { - key: 1234 + key : 1234 }; sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { expect( this ).to.be( context ); done(); } ).withContext(context).withDelay( 200 ); - sDefe.callback( "stuff", { topic : "TestTopic" } ); + sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } ); } ); } ); @@ -188,6 +188,21 @@ describe( "SubscriptionDefinition", function () { done(); }, 2400 ); } ); + + it( "Should keep the context intact", function ( done ) { + var context = { + key : 5678 + }; + sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { + expect( this ).to.be( context ); + done(); + } ).withContext(context).withDebounce( 100 ); + + sDefe.callback.call( sDefe.context, 1 ); + setTimeout( function () { + sDefe.callback.call( sDefe.context, 2 ); + }, 200 ); // should invoke callback + }); } ); describe( "When throttling the callback", function () { @@ -213,5 +228,17 @@ describe( "SubscriptionDefinition", function () { done(); }, 1500 ); } ); + + it( "Should keep the context intact", function ( done ) { + var context = { + key : 'abcd' + }; + sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { + expect( this ).to.be( context ); + done(); + } ).withContext(context).withThrottle( 500 ); + + sDefe.callback.call( sDefe.context, 1 ); + }); } ); } ); \ No newline at end of file From 8bdb2586a6e71e1fbd182cd509df82c4010972fd Mon Sep 17 00:00:00 2001 From: Christian Haas Date: Fri, 6 Sep 2013 21:56:09 +0200 Subject: [PATCH 3/3] Ensuring context in self-disposing callbacks - allowing context modification after delayed configurations --- spec/SubscriptionDefinition.spec.js | 34 +++++++++++++++++++++++++++++ src/SubscriptionDefinition.js | 11 +++++----- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/spec/SubscriptionDefinition.spec.js b/spec/SubscriptionDefinition.spec.js index 45916a3..7606a71 100644 --- a/spec/SubscriptionDefinition.spec.js +++ b/spec/SubscriptionDefinition.spec.js @@ -130,6 +130,17 @@ describe( "SubscriptionDefinition", function () { } ).withContext(context).defer(); sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } ); } ); + + it( "Should keep the context intact when modified later", function ( done ) { + var context = { + key : 1234 + }; + sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { + expect( this ).to.be( context ); + done(); + } ).defer().withContext(context); + sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } ); + } ); } ); describe( "When delaying the callback", function () { @@ -241,4 +252,27 @@ describe( "SubscriptionDefinition", function () { sDefe.callback.call( sDefe.context, 1 ); }); } ); + + describe( "When self disposing", function () { + + it( "Should be inactive", function () { + var sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { + } ).withContext(context).disposeAfter( 1 ); + + sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } ); + + expect( sDefe.inactive ).to.be( true ); + } ); + + it( "Should keep the context intact", function ( done ) { + var context = { + key : 1234 + }; + var sDefe = new SubscriptionDefinition( "TestChannel", "TestTopic", function ( data, env ) { + expect( this ).to.be( context ); + done(); + } ).withContext(context).disposeAfter( 200 ); + sDefe.callback.call( sDefe.context, "stuff", { topic : "TestTopic" } ); + } ); + } ); } ); \ No newline at end of file diff --git a/src/SubscriptionDefinition.js b/src/SubscriptionDefinition.js index ddb78f8..badf0e0 100644 --- a/src/SubscriptionDefinition.js +++ b/src/SubscriptionDefinition.js @@ -36,11 +36,11 @@ SubscriptionDefinition.prototype = { }, defer : function () { + var that = this; var fn = this.callback; - var context = this.context; this.callback = function ( data, env ) { setTimeout( function () { - fn.call( context, data, env ); + fn.call( that.context, data, env ); }, 0 ); }; return this; @@ -50,13 +50,14 @@ SubscriptionDefinition.prototype = { if ( _.isNaN( maxCalls ) || maxCalls <= 0 ) { throw "The value provided to disposeAfter (maxCalls) must be a number greater than zero."; } + var that = this; var fn = this.callback; var dispose = _.after( maxCalls, _.bind( function () { this.unsubscribe(); }, this ) ); this.callback = function () { - fn.apply( this.context, arguments ); + fn.apply( that.context, arguments ); dispose(); }; return this; @@ -113,11 +114,11 @@ SubscriptionDefinition.prototype = { if ( _.isNaN( milliseconds ) ) { throw "Milliseconds must be a number"; } + var that = this; var fn = this.callback; - var context = this.context; this.callback = function ( data, env ) { setTimeout( function () { - fn.call( context, data, env ); + fn.call( that.context, data, env ); }, milliseconds ); }; return this;