Skip to content

Commit

Permalink
Make next method more useful
Browse files Browse the repository at this point in the history
  • Loading branch information
arronzhang committed Dec 9, 2011
1 parent 638ae67 commit a3a1c9a
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 20 deletions.
59 changes: 42 additions & 17 deletions lib/util.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

var jQuery = require("jquery-deferred")
, slice = Array.prototype.slice;
, slice = [].slice
, isFunction = jQuery.isFunction;

exports.parseArgs = parseArgs;
exports.extend = extend;
exports.next = next;
exports.when = jQuery.when;
exports.Deferred = jQuery.Deferred;

function parseArgs (args) {
var all = slice.call(args, 0)
Expand All @@ -21,7 +24,6 @@ function parseArgs (args) {
};
}


function extend(object, fromObject, getters, ignores, originalName, setters) {

originalName = originalName || "original";
Expand Down Expand Up @@ -57,7 +59,7 @@ function extend(object, fromObject, getters, ignores, originalName, setters) {
, callback = args.callback;

// Deferred doesn't support find().each(), beacuse the callback will be called repeatedly
var deferred = jQuery.Deferred();
var dfd = jQuery.Deferred();

self.open( function(err, original) {
if( err ) {
Expand All @@ -73,12 +75,14 @@ function extend(object, fromObject, getters, ignores, originalName, setters) {
callback && callback.apply( self, args );
if ( !args[0] ) {
args.shift();
deferred.resolveWith( self, args );
dfd.resolveWith( self, args );
} else {
deferred.rejectWith( self, args );
dfd.rejectWith( self, args );
}
}
return deferred.promise();
var promise = dfd.promise();
promise.next = next;
return promise;
}
} );
}
Expand All @@ -105,34 +109,55 @@ function extend(object, fromObject, getters, ignores, originalName, setters) {
*/

function next ( firstParam ) {
if( ! jQuery.isFunction( this.promise ) ) {

var isThis = isFunction( this && this.promise )
, len = arguments.length;

if( len > 1 ) {
var args = slice.call( arguments, 0 )
, fn = args.shift()
, promise = isThis ? this.next( fn ) : next( fn );

return promise.next.apply( promise, args );
}

if( ! isThis ) {
//The first deferred
var promise = jQuery.isFunction( firstParam ) ? firstParam() : firstParam;
var promise = isFunction( firstParam ) ? firstParam() : firstParam;
if( !isFunction( promise && promise.promise ) ) {
promise = len ? jQuery.when( promise ) : jQuery.when();
}
promise.next = next;
return promise;
}

var dfd = jQuery.Deferred();
this.done( function() {
var last = slice.call( arguments )
, res;
try{
res = firstParam.apply( null, last );
try {
res = isFunction(firstParam) ? firstParam.apply( null, last ) : firstParam;
} catch( e ) {
res = e;
}
jQuery.isFunction( res && res.promise ) ?
res.done( function() {
var args = slice.call( arguments );
for (var i = last.length - 1; i >= 0; i--) {
args.unshift( last[i] );
if( res instanceof Error ) {
dfd.reject( res );
} else {
res = isFunction( res && res.promise ) ? res : jQuery.when( res );
res.done( function( value ) {
var args = [ arguments.length > 1 ? slice.call( arguments, 0 ) : value ]
, i = last.length;
while( i ) {
args.unshift( last[ --i ] );
}
dfd.resolve.apply( dfd, args );
} ).fail( dfd.reject )
: dfd.reject( res );
} ).fail( dfd.reject );
}

} ).fail( dfd.reject );

var promise = dfd.promise();
promise.next = next;
return promise;
}

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}
, "dependencies": {
"mongodb" : ">=0.9.1"
, "jquery-deferred": ">=0.1.0"
, "jquery-deferred": ">=0.2.0"
}
, "devDependencies": {
"mocha" : "*"
Expand Down
171 changes: 169 additions & 2 deletions test/util.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

var mongoq = require('../index.js')
, util = mongoq.util
, should = require('should');
, util = mongoq.util
, should = require('should');

describe( "util", function() {
it( 'test util parseArgs', function(){
Expand All @@ -25,4 +25,171 @@ describe( "util", function() {
});
});

describe( "next", function() {
var successPromise = function(val) {
var dfd = util.Deferred();
var args = [].slice.call( arguments, 0 );
setTimeout( function() {
dfd.resolve.apply( dfd, args );
} ,40 );
var p = dfd.promise();
p.next = util.next;
return p;
}
, failPromise = function(val) {
var dfd = util.Deferred();
setTimeout( function() {
dfd.reject( val );
} ,40 );
var p = dfd.promise();
p.next = util.next;
return p;
};

it( "should success to next", function( done ) {
util.next( successPromise("v1") )
.next( function(v1) {
return successPromise( "v2", "v21" );
})
.next( function(v1, v2) {
return successPromise( );
})
.next( function(v1, v2, v3) {
return successPromise( "v4", "v41" );
})
.done( function(v1, v2, v3, v4) {
v1.should.be.eql("v1");
v2.should.be.eql(["v2", "v21"]);
should.not.exist( v3 );
v4.should.be.eql(["v4", "v41"]);
arguments.should.have.length( 4 );
done();
})
.fail(function() {
false.should.be.true;
});
} );

it( "should support anything value", function( done ) {
util.next()
.next( successPromise("v1") )
.next( function(v1) {
return successPromise( "v2", "v21" );
})
.next( "v3" )
.done( function(v1, v2, v3) {
v1.should.be.equal("v1");
v2.should.be.eql(["v2", "v21"]);
v3.should.be.equal("v3");
arguments.should.have.length( 3 );
done();
})
.fail(function() {
false.should.be.true;
} );
} );

it( "should have next method", function( done ) {
successPromise("v1")
.next( function(v1) {
return successPromise( "v2" );
})
.next( function(v1, v2) {
return successPromise( "v3" );
})
.next( function(v1, v2, v3) {
return successPromise( "v4" );
})
.done( function(v1, v2, v3, v4) {
v1.should.be.equal("v1");
v2.should.be.equal("v2");
v3.should.be.equal("v3");
v4.should.be.equal("v4");
arguments.should.have.length( 4 );
done();
})
.fail(function() {
false.should.be.true;
} );
} );

it( "should support failed message", function( done ) {
successPromise("v1")
.next( function(v1) {
return successPromise( "v2" );
})
.next( function(v1, v2) {
return failPromise( "e3" );
})
.done( function(v1, v2, v3) {
false.should.be.true;
})
.fail( function( err ) {
err.should.be.equal("e3");
done();
});
} );

it( "should support failed message return", function( done ) {
successPromise("v1")
.next( function(v1) {
return successPromise( "v2" );
})
.next( function(v1, v2) {
return new Error( "e3" );
})
.done( function(v1, v2, v3) {
false.should.be.true;
})
.fail( function( err ) {
err.message.should.be.equal("e3");
done();
});
} );

it( "should support throw error", function( done ) {
successPromise("v1")
.next( function(v1) {
return successPromise( "v2" );
})
.next( function(v1, v2) {
throw new Error("e3");
})
.done( function(v1, v2, v3) {
false.should.be.true;
})
.fail( function( err ) {
err.message.should.be.equal("e3");
done();
});
} );

it( "should multi arguments", function( done ) {
util.next(
successPromise("v1")
, function(v1) {
return successPromise( "v2", "v21" );
}
, function(v1, v2) {
return successPromise( );
}
, function(v1, v2, v3) {
return successPromise( "v4", "v41" );
}
)
.done( function(v1, v2, v3, v4) {
v1.should.be.eql("v1");
v2.should.be.eql(["v2", "v21"]);
should.not.exist( v3 );
v4.should.be.eql(["v4", "v41"]);
arguments.should.have.length( 4 );
done();
})
.fail(function() {
false.should.be.true;
});
} );

} );

});

0 comments on commit a3a1c9a

Please sign in to comment.