Skip to content

Commit

Permalink
Allow services to return a promise instead of calling the callback (#41
Browse files Browse the repository at this point in the history
…).
  • Loading branch information
daffl committed Apr 25, 2014
1 parent 5900114 commit c31fca3
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 7 deletions.
3 changes: 2 additions & 1 deletion lib/mixins/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';

module.exports = [
require('./event')
require('./promise'),
require('./event')
];
28 changes: 28 additions & 0 deletions lib/mixins/promise.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

var _ = require('lodash');
var makeWrapper = function() {
return function() {
var result = this._super.apply(this, arguments);
var callback = arguments[arguments.length - 1];

if(typeof result !== 'undefined' && _.isFunction(result.then) && _.isFunction(callback)) {
result.then(function(data) {
callback(null, data);
}, function(error) {
callback(error);
});
}
return result;
};
};

module.exports = function (service) {
if (typeof service.mixin === 'function') {
var mixin = _.transform(_.pick(service, this.methods), function(result, num, key) {
result[key] = makeWrapper();
});

service.mixin(mixin);
}
};
2 changes: 2 additions & 0 deletions lib/providers/rest/wrappers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict';

var _ = require('lodash');

// A function that returns the middleware for a given method and service
Expand Down
2 changes: 2 additions & 0 deletions lib/providers/socket/commons.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict';

var _ = require('lodash');

// The position of the params parameters for a service method so that we can extend them
Expand Down
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@
"body-parser": "~1.0.2"
},
"devDependencies": {
"request": "~2.x",
"socket.io-client": "~0.9.0",
"grunt-cli": "~0.1.0",
"grunt": "~0.4.0",
"grunt-release": "~0.5.0",
"mocha": "~1.x",
"grunt-cli": "~0.1.0",
"grunt-contrib-jshint": "~0.x",
"grunt-jsbeautifier": "~0.2.0",
"grunt-release": "~0.5.0",
"grunt-simple-mocha": "~0.4.0",
"grunt-jsbeautifier": "~0.2.0"
"mocha": "~1.x",
"q": "^1.0.1",
"request": "~2.x",
"socket.io-client": "~0.9.0"
}
}
27 changes: 27 additions & 0 deletions test/application.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var io = require('socket.io-client');
var request = require('request');
var https = require('https');
var fs = require('fs');
var q = require('q');

var feathers = require('../lib/feathers');

Expand Down Expand Up @@ -186,4 +187,30 @@ describe('Feathers application', function () {
});
});
});

it('returns the value of a promise (#41)', function (done) {
var original = {};
var todoService = {
get: function (name) {
original = {
id: name,
q: true,
description: "You have to do " + name + "!"
};
return q(original);
}
};

var app = feathers()
.configure(feathers.rest())
.use('/todo', todoService);

var server = app.listen(6880).on('listening', function () {
request('http://localhost:6880/todo/dishes', function (error, response, body) {
assert.ok(response.statusCode === 200, 'Got OK status code');
assert.deepEqual(original, JSON.parse(body));
server.close(done);
});
});
});
});
93 changes: 93 additions & 0 deletions test/mixins/promise.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict';

var assert = require('assert');
var Proto = require('uberproto');
var q = require('q');
var _ = require('lodash');

var mixin = require('../../lib/mixins/promise');

describe('Promises/A+ mixin', function () {
it('Calls a callback when a promise is returned from the original service', function (done) {
// A dummy context (this will normally be the application)
var context = {
methods: ['get']
};
var FixtureService = Proto.extend({
get: function (id) {
return q({
id: id,
description: 'You have to do ' + id
});
}
});

mixin.call(context, FixtureService);

var instance = Proto.create.call(FixtureService);
instance.get('dishes', {}, function (error, data) {
assert.deepEqual(data, {
id: 'dishes',
description: 'You have to do dishes'
});
done();
});
});

it('calls back with an error for a failing deferred', function(done) {
// A dummy context (this will normally be the application)
var context = {
methods: ['get']
};
var FixtureService = Proto.extend({
get: function () {
var dfd = q.defer();

_.defer(function() {
dfd.reject(new Error('Something went wrong'));
});

return dfd.promise;
}
});

mixin.call(context, FixtureService);

var instance = Proto.create.call(FixtureService);
instance.get('dishes', {}, function (error) {
assert.ok(error);
assert.equal(error.message, 'Something went wrong');
done();
});
});

it('does not try to call the callback if it does not exist', function(done) {
// A dummy context (this will normally be the application)
var context = {
methods: ['create']
};
var FixtureService = Proto.extend({
create: function (data) {
var dfd = q.defer();

_.defer(function() {
dfd.resolve(data);
});

return dfd.promise;
}
});
var original = {
id: 'laundry',
description: 'You have to do laundry'
};

mixin.call(context, FixtureService);

var instance = Proto.create.call(FixtureService);
instance.create(original, {}).then(function(data) {
assert.deepEqual(data, original);
done();
});
});
});

0 comments on commit c31fca3

Please sign in to comment.