Skip to content
This repository was archived by the owner on Apr 20, 2018. It is now read-only.

Commit 9bc9006

Browse files
committed
Allow hooks to return a promise (#3).
1 parent bd07bd7 commit 9bc9006

File tree

6 files changed

+221
-104
lines changed

6 files changed

+221
-104
lines changed

.jshintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"immed": true,
99
"indent": 2,
1010
"latedef": "nofunc",
11-
"newcap": true,
11+
"newcap": false,
1212
"noarg": true,
1313
"quotmark": "single",
1414
"regexp": true,

lib/after.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ module.exports = function (service) {
4444
hookObject.result = result;
4545

4646
// Call the hook object
47-
hook.call(self, hookObject, hookCallback);
47+
var promise = hook.call(self, hookObject, hookCallback);
48+
if(typeof promise !== 'undefined' && typeof promise.then === 'function') {
49+
promise.then(function() {
50+
hookCallback();
51+
}, function(error) {
52+
hookCallback(error);
53+
});
54+
}
4855
};
4956

5057
hookObject.type = 'after';

lib/before.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,15 @@ module.exports = function (service) {
3636
};
3737

3838
hookObject.type = 'before';
39-
hook.call(self, hookObject, hookCallback);
39+
40+
var promise = hook.call(self, hookObject, hookCallback);
41+
if(typeof promise !== 'undefined' && typeof promise.then === 'function') {
42+
promise.then(function() {
43+
hookCallback();
44+
}, function(error) {
45+
hookCallback(error);
46+
});
47+
}
4048
};
4149
});
4250

package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@
4040
"lodash": "^2.4.1"
4141
},
4242
"devDependencies": {
43-
"mocha": "*",
44-
"grunt-cli": "~0.1.7",
43+
"feathers": "1.0.0-pre.1",
4544
"grunt": "~0.4.1",
46-
"grunt-release": "~0.5.1",
45+
"grunt-cli": "~0.1.7",
4746
"grunt-contrib-jshint": "~0.x",
48-
"grunt-simple-mocha": "~0.4.0",
4947
"grunt-contrib-watch": "~0.5.3",
50-
"feathers": "^0.4.0"
48+
"grunt-release": "~0.5.1",
49+
"grunt-simple-mocha": "~0.4.0",
50+
"mocha": "*",
51+
"q": "^1.0.1"
5152
},
5253
"peerDependencies": {
5354
"feathers": ">= 0.3.0"

test/after.test.js

+148-96
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,165 @@
11
var assert = require('assert');
2+
var Q = require('q');
23
var feathers = require('feathers');
34

45
var hooks = require('../lib/hooks');
56

67
describe('.after hooks', function () {
7-
it('gets mixed into a service and modifies data', function (done) {
8-
var dummyService = {
9-
after: {
10-
create: function (hook, next) {
8+
it('gets mixed into a service and modifies data', function (done) {
9+
var dummyService = {
10+
after: {
11+
create: function (hook, next) {
1112
assert.equal(hook.type, 'after');
1213

1314
hook.result.some = 'thing';
1415

1516
next(null, hook);
16-
}
17-
},
18-
19-
create: function (data, params, callback) {
20-
callback(null, data);
21-
}
22-
};
23-
24-
var app = feathers().configure(hooks()).use('/dummy', dummyService);
25-
var service = app.lookup('dummy');
26-
27-
service.create({ my: 'data' }, {}, function(error, data) {
28-
assert.deepEqual({ my: 'data', some: 'thing' }, data, 'Got modified data');
29-
done();
30-
});
31-
});
32-
33-
it('returns errors', function (done) {
34-
var dummyService = {
35-
after: {
36-
update: function (hook, next) {
37-
next(new Error('This did not work'));
38-
}
39-
},
40-
41-
update: function (id, data, params, callback) {
42-
callback(null, data);
43-
}
44-
};
45-
46-
var app = feathers().configure(hooks()).use('/dummy', dummyService);
47-
var service = app.lookup('dummy');
48-
49-
service.update(1, { my: 'data' }, {}, function(error) {
50-
assert.ok(error, 'Got an error');
51-
assert.equal(error.message, 'This did not work', 'Got expected error message from hook');
52-
done();
53-
});
54-
});
55-
56-
it('does not run after hook when there is an error', function (done) {
57-
var dummyService = {
58-
after: {
59-
remove: function () {
60-
assert.ok(false, 'This should never get called');
61-
}
62-
},
63-
64-
remove: function (id, params, callback) {
65-
callback(new Error('Error removing item'));
66-
}
67-
};
68-
69-
var app = feathers().configure(hooks()).use('/dummy', dummyService);
70-
var service = app.lookup('dummy');
71-
72-
service.remove(1, {}, function(error) {
73-
assert.ok(error, 'Got error');
74-
assert.equal(error.message, 'Error removing item', 'Got error message from service');
75-
done();
76-
});
77-
});
78-
79-
it('adds .after() and chains multiple calls', function (done) {
80-
var dummyService = {
81-
create: function (data, params, callback) {
82-
callback(null, data);
83-
}
84-
};
85-
86-
var app = feathers().configure(hooks()).use('/dummy', dummyService);
87-
var service = app.lookup('dummy');
88-
89-
service.after({
90-
create: function (hook, next) {
17+
}
18+
},
19+
20+
create: function (data, params, callback) {
21+
callback(null, data);
22+
}
23+
};
24+
25+
var app = feathers().configure(hooks()).use('/dummy', dummyService);
26+
var service = app.lookup('dummy');
27+
28+
service.create({ my: 'data' }, {}, function (error, data) {
29+
assert.deepEqual({ my: 'data', some: 'thing' }, data, 'Got modified data');
30+
done();
31+
});
32+
});
33+
34+
it('returns errors', function (done) {
35+
var dummyService = {
36+
after: {
37+
update: function (hook, next) {
38+
next(new Error('This did not work'));
39+
}
40+
},
41+
42+
update: function (id, data, params, callback) {
43+
callback(null, data);
44+
}
45+
};
46+
47+
var app = feathers().configure(hooks()).use('/dummy', dummyService);
48+
var service = app.lookup('dummy');
49+
50+
service.update(1, { my: 'data' }, {}, function (error) {
51+
assert.ok(error, 'Got an error');
52+
assert.equal(error.message, 'This did not work', 'Got expected error message from hook');
53+
done();
54+
});
55+
});
56+
57+
it('does not run after hook when there is an error', function (done) {
58+
var dummyService = {
59+
after: {
60+
remove: function () {
61+
assert.ok(false, 'This should never get called');
62+
}
63+
},
64+
65+
remove: function (id, params, callback) {
66+
callback(new Error('Error removing item'));
67+
}
68+
};
69+
70+
var app = feathers().configure(hooks()).use('/dummy', dummyService);
71+
var service = app.lookup('dummy');
72+
73+
service.remove(1, {}, function (error) {
74+
assert.ok(error, 'Got error');
75+
assert.equal(error.message, 'Error removing item', 'Got error message from service');
76+
done();
77+
});
78+
});
79+
80+
it('adds .after() and chains multiple calls', function (done) {
81+
var dummyService = {
82+
create: function (data, params, callback) {
83+
callback(null, data);
84+
}
85+
};
86+
87+
var app = feathers().configure(hooks()).use('/dummy', dummyService);
88+
var service = app.lookup('dummy');
89+
90+
service.after({
91+
create: function (hook, next) {
9192
hook.result.some = 'thing';
92-
next();
93-
}
94-
});
93+
next();
94+
}
95+
});
9596

96-
service.after({
97-
create: function (hook, next) {
97+
service.after({
98+
create: function (hook, next) {
9899
hook.result.other = 'stuff';
99100

100101
next();
101-
}
102-
});
103-
104-
service.create({ my: 'data' }, {}, function(error, data) {
105-
assert.deepEqual({
106-
my: 'data',
107-
some: 'thing',
108-
other: 'stuff'
109-
}, data, 'Got modified data');
110-
done();
111-
});
112-
});
102+
}
103+
});
104+
105+
service.create({ my: 'data' }, {}, function (error, data) {
106+
assert.deepEqual({
107+
my: 'data',
108+
some: 'thing',
109+
other: 'stuff'
110+
}, data, 'Got modified data');
111+
done();
112+
});
113+
});
114+
115+
it('.after hooks can return a promise', function (done) {
116+
var app = feathers().configure(hooks()).use('/dummy', {
117+
get: function (id) {
118+
return Q({
119+
id: id,
120+
description: 'You have to do ' + id
121+
});
122+
},
123+
124+
find: function () {
125+
return Q([]);
126+
}
127+
});
128+
var service = app.lookup('dummy');
129+
130+
service.after({
131+
get: function (hook) {
132+
var dfd = Q.defer();
133+
134+
setTimeout(function () {
135+
hook.result.ran = true;
136+
dfd.resolve();
137+
}, 50);
138+
139+
return dfd.promise;
140+
},
141+
142+
find: function() {
143+
var dfd = Q.defer();
144+
145+
setTimeout(function() {
146+
dfd.reject(new Error('You can not see this'));
147+
}, 50);
148+
149+
return dfd.promise;
150+
}
151+
});
152+
153+
service.get('laundry', {}, function (error, data) {
154+
assert.deepEqual(data, {
155+
id: 'laundry',
156+
description: 'You have to do laundry',
157+
ran: true
158+
});
159+
service.find({}, function(error) {
160+
assert.equal(error.message, 'You can not see this');
161+
done();
162+
});
163+
});
164+
});
113165
});

test/before.test.js

+49
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var _ = require('lodash');
2+
var Q = require('q');
23
var assert = require('assert');
34
var feathers = require('feathers');
45

@@ -140,4 +141,52 @@ describe('.before hooks', function () {
140141
done();
141142
});
142143
});
144+
145+
it('.before hooks can return a promise', function(done) {
146+
var app = feathers().configure(hooks()).use('/dummy', {
147+
get: function(id, params) {
148+
assert.ok(params.ran, 'Ran through promise hook');
149+
150+
return Q({
151+
id: id,
152+
description: 'You have to do ' + id
153+
});
154+
},
155+
156+
remove: function() {
157+
assert.ok(false, 'Should never get here');
158+
}
159+
});
160+
var service = app.lookup('dummy');
161+
162+
service.before({
163+
get: function(hook) {
164+
var dfd = Q.defer();
165+
166+
setTimeout(function() {
167+
hook.params.ran = true;
168+
dfd.resolve();
169+
}, 50);
170+
171+
return dfd.promise;
172+
},
173+
174+
remove: function() {
175+
var dfd = Q.defer();
176+
177+
setTimeout(function() {
178+
dfd.reject(new Error('This did not work'));
179+
}, 50);
180+
181+
return dfd.promise;
182+
}
183+
});
184+
185+
service.get('dishes', {}, function() {
186+
service.remove(10, {}, function(error) {
187+
assert.equal(error.message, 'This did not work');
188+
done();
189+
});
190+
});
191+
});
143192
});

0 commit comments

Comments
 (0)