Browse files

Added defer keyword for callback based blocks

  • Loading branch information...
1 parent 7ee7d0d commit 21f2fd4d6214dc6315675a9e88b5e2a43bfee8bb @foobarfighter committed Jan 29, 2012
View
1 build/build.json
@@ -8,6 +8,7 @@
, "src/block.js"
, "src/polling_block.js"
, "src/timeout_block.js"
+ , "src/timed_deferred_block.js"
, "src/example.js"
, "src/example_group.js"
, "src/expectation.js"
View
31 spec/shared/keyword_spec.js
@@ -227,5 +227,36 @@ foounit.add(function (kw){ with(kw){
});
});
+ describe('defer', function (){
+ var bc;
+ before(function (){
+ footest.setBuildContext(new footest.BuildContext());
+ mock(footest, 'setTimeout', function (func){ func(); });
+ });
+
+ after(function (){
+ footest.setBuildContext(bc);
+ });
+
+ it('enqueues a TimedDeferredBlock', function (){
+ var block, called;
+
+ var example = new footest.Example('example', function (){
+ var blockQueue = footest.getBuildContext()
+ .getCurrentExample()
+ .getCurrentBlockQueue();
+
+ block = footest.keywords.defer(function (block){
+ called = true;
+ expect(typeof block.complete).to(equal, 'function');
+ });
+ });
+
+ example.run();
+ expect(called).to(beTrue);
+ });
+ });
+
+
});
}});
View
48 spec/shared/timed_deferred_block_spec.js
@@ -0,0 +1,48 @@
+var footest = foounit.require(':src/foounit');
+
+foounit.add(function (kw){ with(kw){
+ describe('foounit.TimedDeferredBlock', function (){
+ describe('run', function (){
+ var block, callback;
+
+ before(function (){
+ callback = mockEmpty();
+ block = new footest.TimedDeferredBlock(callback, 100);
+ block.run();
+ mock(foounit, 'clearTimeout');
+ });
+
+ after(function (){
+ expect(callback).to(haveBeenCalled, withArgs(block));
+ expect(foounit.clearTimeout.totalCalls).to(beGt, 0);
+ });
+
+ it('completes when complete is called', function (){
+ var complete = block.onComplete = mock(function (){});
+ block.complete();
+ expect(complete).to(haveBeenCalled);
+ });
+
+ it('fails when fail is called', function (){
+ var failure = block.onFailure = mockEmpty();
+
+ block.fail('expected');
+ expect(failure).to(haveBeenCalled);
+ expect(block.getException()).to(match, /expected/);
+ });
+
+ it('fails when the timeout is reached', function (){
+ var log = []
+ , timeout = block.onTimeout = mock(function (){ log.push('timeout'); })
+ , failure = block.onFailure = mock(function (){ log.push('failure'); });
+
+ //block.run();
+
+ waitFor(function (){
+ expect(log).to(equal, ['timeout', 'failure']);
+ expect(block.getException()).to(match, /timeout reached/);
+ });
+ });
+ });
+ });
+}});
View
3 src/adapters/node.js
@@ -13,9 +13,10 @@ foounit.mixin(foounit, require('../example_group'));
foounit.mixin(foounit, require('../expectation'));
foounit.mixin(foounit, require('../keywords'));
foounit.mixin(foounit, require('../matchers'));
+foounit.mixin(foounit, require('../suite'));
foounit.mixin(foounit, require('../mock/screw_compat'));
foounit.mixin(foounit, require('../polling_block'));
-foounit.mixin(foounit, require('../suite'));
+foounit.mixin(foounit, require('../timed_deferred_block'));
foounit.mixin(foounit, require('../timeout_block'));
// foounit command line interface
View
22 src/keywords.js
@@ -88,8 +88,7 @@ foounit.addKeyword('waitFor', function (func, timeout){
var example = foounit.getBuildContext().getCurrentExample()
, block = new foounit.PollingBlock(func, timeout || foounit.settings.waitForTimeout);
- example.enqueue(block);
- return block;
+ return example.enqueue(block);
});
/**
@@ -99,8 +98,7 @@ foounit.addKeyword('waitForTimeout', function (func, timeout){
var example = foounit.getBuildContext().getCurrentExample()
, block = new foounit.TimeoutBlock(func, timeout || foounit.settings.waitForTimeout);
- example.enqueue(block);
- return block;
+ return example.enqueue(block);
});
@@ -111,6 +109,18 @@ foounit.addKeyword('run', function (func){
var example = foounit.getBuildContext().getCurrentExample()
, block = new foounit.Block(func);
- example.enqueue(block);
- return block;
+ return example.enqueue(block);
});
+
+/**
+ * Adds a deferred block to the current block queue that fails when fail() is called
+ * or complete() is not called within the timeout .
+ */
+foounit.addKeyword('defer', function (func, timeout){
+ var example = foounit.getBuildContext().getCurrentExample()
+ , block = new foounit.TimedDeferredBlock(func, timeout);
+
+ return example.enqueue(block);
+});
+
+
View
33 src/timed_deferred_block.js
@@ -0,0 +1,33 @@
+foounit.TimedDeferredBlock = function (func, timeout){
+ this._func = func;
+ this._timeout = timeout == null ? foounit.settings.waitForTimeout : timeout;
+}
+
+foounit.mixin(foounit.TimedDeferredBlock.prototype, foounit.Block.prototype);
+foounit.mixin(foounit.TimedDeferredBlock.prototype, {
+ getTimeout: function (){ return this._timeout; }
+
+ , onTimeout: function (){}
+
+ , run: function (){
+ var self = this;
+
+ this._hTimeout = foounit.setTimeout(function (){
+ self.onTimeout(self);
+ self.fail('timeout reached');
+ }, this._timeout);
+
+ this._func.apply({}, [this]);
+ }
+
+ , complete: function (){
+ foounit.clearTimeout(this._hTimeout);
+ this.onComplete(this);
+ }
+
+ , fail: function (exception){
+ foounit.clearTimeout(this._hTimeout);
+ this._exception = exception instanceof Error ? exception : new Error(exception);
+ this.onFailure(this);
+ }
+});

0 comments on commit 21f2fd4

Please sign in to comment.