Skip to content
Browse files

Migration to ES6 and API providers in separate modules

1 parent 61c2310 commit f66c7d5b071302526e31cc7749ddd177ff9e31a2 @daffl daffl committed
View
4 .babelrc
@@ -0,0 +1,4 @@
+{
+ "plugins": [ "add-module-exports" ],
+ "presets": [ "es2015" ]
+}
View
4 .gitignore
@@ -29,3 +29,7 @@ node_modules
tmp*
.idea/
+
+
+# The compiled/babelified modules
+lib/
View
42 .jshintrc
@@ -1,14 +1,30 @@
{
- "globals": {
- "it": true,
- "describe": true,
- "before": true,
- "beforeEach": true,
- "after": true,
- "afterEach": true,
- "exports": true
- },
- "unused": true,
- "undef": true,
- "node": true
-}
+ "node": true,
+ "esnext": true,
+ "bitwise": true,
+ "camelcase": true,
+ "curly": true,
+ "eqeqeq": true,
+ "immed": true,
+ "indent": 2,
+ "latedef": "nofunc",
+ "newcap": false,
+ "noarg": true,
+ "quotmark": "single",
+ "regexp": true,
+ "undef": true,
+ "unused": true,
+ "strict": false,
+ "trailing": true,
+ "smarttabs": true,
+ "white": false,
+ "node": true,
+ "globals": {
+ "it": true,
+ "describe": true,
+ "before": true,
+ "beforeEach": true,
+ "after": true,
+ "afterEach": true
+ }
+}
View
8 .npmignore
@@ -0,0 +1,8 @@
+./.editorconfig
+./.jshintrc
+./.travis.yml
+./.babelrc
+.idea/
+src/
+test/
+!lib/
View
8 contributing.md
@@ -12,6 +12,14 @@ If you have any other questions, feel free to submit post them on [Stackoverflow
Before running the tests from the `test/` folder `npm test` will run JSHint. You can check your code changes individually by running `npm run jshint`.
+## ES6 compilation
+
+Feathers uses [Babel](https://babeljs.io/) to leverage the latest developments of the JavaScript language. All code and samples are currently written in ES2015. To transpile the code in this repository run
+
+> npm run compile
+
+__Note:__ `npm test` will run the compilation automatically before the tests.
+
## Tests
[Mocha](http://mochajs.org/) tests are located in the `test/` folder and can be run using the `npm run mocha` or `npm test` (with JSHint) command.
View
41 lib/feathers.js
@@ -1,41 +0,0 @@
-'use strict';
-
-var _ = require('lodash');
-var express = require('express');
-var Proto = require('uberproto');
-var Application = require('./application');
-var providers = require('./providers');
-var errors = require('feathers-errors');
-
-/**
- * Create a Feathers application that extends Express.
- *
- * @return {Function}
- * @api public
- */
-
-function createApplication() {
- var app = express();
- Proto.mixin(Application, app);
- app.init();
- return app;
-}
-
-/**
- * Expose `createApplication()`.
- */
-module.exports = createApplication;
-
-/**
- * Framework version.
- */
-exports.version = require('../package.json').version;
-
-// Add the providers (REST and SocketIO)
-_.defaults(module.exports, providers);
-
-// Add the error handling
-_.defaults(module.exports, errors);
-
-// Expose all express methods (like express.engine())
-_.defaults(module.exports, express);
View
57 lib/mixins/event.js
@@ -1,57 +0,0 @@
-'use strict';
-
-var _ = require('lodash');
-var rubberduck = require('rubberduck');
-var EventEmitter = require('events').EventEmitter;
-var hookObject = require('feathers-commons').hooks.hookObject;
-var eventMappings = {
- create: 'created',
- update: 'updated',
- remove: 'removed',
- patch: 'patched'
-};
-
-module.exports = function (service) {
- var isEmitter = typeof service.on === 'function' &&
- typeof service.emit === 'function';
- var emitter = service._rubberDuck = rubberduck.emitter(service);
-
- if (typeof service.mixin === 'function') {
- if(!isEmitter) {
- service.mixin(EventEmitter.prototype);
- }
- }
-
- service._serviceEvents = _.isArray(service.events) ? service.events.slice() : [];
-
- // Pass the Rubberduck error event through
- // TODO deal with error events properly
- emitter.on('error', function (errors) {
- service.emit('serviceError', errors[0]);
- });
-
- _.each(eventMappings, function (event, method) {
- var alreadyEmits = service._serviceEvents.indexOf(event) !== -1;
-
- if (typeof service[method] === 'function' && !alreadyEmits) {
- // The Rubberduck event name (e.g. afterCreate, afterUpdate or afterDestroy)
- var eventName = 'after' + method.charAt(0).toUpperCase() + method.substring(1);
- service._serviceEvents.push(event);
- // Punch the given method
- emitter.punch(method, -1);
- // Pass the event and error event through
- emitter.on(eventName, function (results, args) {
- if (!results[0]) { // callback without error
- var hook = hookObject(method, 'after', args);
- var data = Array.isArray(results[1]) ? results[1] : [ results[1] ];
-
- data.forEach(function(current) {
- service.emit(event, current, hook);
- });
- } else {
- service.emit('serviceError', results[0]);
- }
- });
- }
- });
-};
View
19 lib/mixins/normalizer.js
@@ -1,19 +0,0 @@
-var _ = require('lodash');
-var getArguments = require('feathers-commons').getArguments;
-
-module.exports = function (service) {
- if (typeof service.mixin === 'function') {
- var mixin = {};
-
- _.each(this.methods, function(method) {
- if(typeof service[method] === 'function') {
- mixin[method] = function() {
- var args = getArguments(method, arguments);
- return this._super.apply(this, args);
- };
- }
- });
-
- service.mixin(mixin);
- }
-};
View
31 lib/mixins/promise.js
@@ -1,31 +0,0 @@
-'use strict';
-
-var _ = require('lodash');
-
-var wrapper = 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 = {};
-
- _.each(this.methods, function(method) {
- if(typeof service[method] === 'function') {
- mixin[method] = wrapper;
- }
- });
-
- service.mixin(mixin);
- }
-};
View
7 lib/providers/index.js
@@ -1,7 +0,0 @@
-'use strict';
-
-module.exports = {
- rest: require('./rest'),
- socketio: require('./socket/socketio'),
- primus: require('./socket/primus')
-};
View
72 lib/providers/rest/index.js
@@ -1,72 +0,0 @@
-'use strict';
-
-var wrappers = require('./wrappers');
-var debug = require('debug')('feathers:rest');
-
-module.exports = function (config) {
- config = config || {};
-
- var handler = config.handler || function (req, res) {
- res.format({
- 'application/json': function () {
- res.json(res.data);
- }
- });
- };
-
- if (typeof config === 'function') {
- handler = config;
- }
-
- return function () {
- var app = this;
-
- app.enable('feathers rest');
-
- debug('Setting up default middleware for REST handler');
-
- app.use(function (req, res, next) {
- req.feathers = {};
- next();
- });
-
- app.rest = wrappers;
-
- // Register the REST provider
- app.providers.push(function (path, service, options) {
- if (app.disabled('feathers rest')) {
- return;
- }
-
- var middleware = (options || {}).middleware || {};
- var before = middleware.before || [];
- var after = middleware.after || [];
-
- var uri = path.indexOf('/') === 0 ? path : '/' + path;
- var baseRoute = app.route(uri);
- var idRoute = app.route(uri + '/:id');
-
- debug('Adding REST provider for service `' + path + '` at base route `' + uri + '`');
-
- // GET / -> service.find(cb, params)
- baseRoute.get.apply(baseRoute, before.concat(app.rest.find(service), after, handler));
- // POST / -> service.create(data, params, cb)
- baseRoute.post.apply(baseRoute, before.concat(app.rest.create(service), after, handler));
- // PATCH / -> service.patch(null, data, params)
- baseRoute.patch.apply(baseRoute, before.concat(app.rest.patch(service), after, handler));
- // PUT / -> service.update(null, data, params)
- baseRoute.put.apply(baseRoute, before.concat(app.rest.update(service), after, handler));
- // DELETE / -> service.remove(null, params)
- baseRoute.delete.apply(baseRoute, before.concat(app.rest.remove(service), after, handler));
-
- // GET /:id -> service.get(id, params, cb)
- idRoute.get.apply(idRoute, before.concat(app.rest.get(service), after, handler));
- // PUT /:id -> service.update(id, data, params, cb)
- idRoute.put.apply(idRoute, before.concat(app.rest.update(service), after, handler));
- // PATCH /:id -> service.patch(id, data, params, callback)
- idRoute.patch.apply(idRoute, before.concat(app.rest.patch(service), after, handler));
- // DELETE /:id -> service.remove(id, params, cb)
- idRoute.delete.apply(idRoute, before.concat(app.rest.remove(service), after, handler));
- });
- };
-};
View
81 lib/providers/rest/wrappers.js
@@ -1,81 +0,0 @@
-'use strict';
-
-var _ = require('lodash');
-var debug = require('debug')('feathers:rest');
-var errors = require('feathers-errors');
-var status = {
- created: 201,
- noContent: 204,
- methodNotAllowed: 405
-};
-
-// A function that returns the middleware for a given method and service
-// `getArgs` is a function that should return additional leading service arguments
-function getHandler (method, getArgs, service) {
- return function (req, res, next) {
- // Check if the method exists on the service at all. Send 405 (Method not allowed) if not
- if (typeof service[method] !== 'function') {
- debug('Method `' + method + '` not allowed on `' + req.url + '`');
- res.status(status.methodNotAllowed);
- return next(new errors.types.MethodNotAllowed('Method `' + method + '` is not supported by this endpoint.'));
- }
-
- // Run the getArgs callback, if available, for additional parameters
- var args = getArgs(req, res, next);
- // Grab the service parameters. Use req.feathers and set the query to req.query
- var params = _.extend({ query: req.query || {} }, _.omit(req.params || {}, 'id'), req.feathers);
- // The service success callback which sets res.data or calls next() with the error
- var callback = function (error, data) {
- if (error) {
- debug('Error in REST handler: `' + (error.message || error) + '`');
- return next(error);
- }
-
- res.data = data;
-
- if(!data) {
- debug('No content returned for `' + req.url + '`');
- res.status(status.noContent);
- } else if(method === 'create') {
- res.status(status.created);
- }
-
- return next();
- };
-
- debug('REST handler calling `' + method + '` from `' + req.url + '`');
- service[method].apply(service, args.concat([ params, callback ]));
- };
-}
-
-// Returns no leading parameters
-function reqNone () {
- return [];
-}
-
-// Returns the leading parameters for a `get` or `remove` request (the id)
-function reqId (req) {
- return [ req.params.id || null ];
-}
-
-// Returns the leading parameters for an `update` or `patch` request (id, data)
-function reqUpdate (req) {
- return [ req.params.id || null, req.body ];
-}
-
-// Returns the leading parameters for a `create` request (data)
-function reqCreate (req) {
- return [ req.body ];
-}
-
-// Returns wrapped middleware for a service method.
-// Doing some fancy ES 5 .bind argument currying for .getHandler()
-// Basically what you are getting for each is a function(service) {}
-module.exports = {
- find: getHandler.bind(null, 'find', reqNone),
- get: getHandler.bind(null, 'get', reqId),
- create: getHandler.bind(null, 'create', reqCreate),
- update: getHandler.bind(null, 'update', reqUpdate),
- patch: getHandler.bind(null, 'patch', reqUpdate),
- remove: getHandler.bind(null, 'remove', reqId)
-};
View
54 lib/providers/socket/primus.js
@@ -1,54 +0,0 @@
-'use strict';
-
-var Proto = require('uberproto');
-var Primus = require('primus');
-var Emitter = require('primus-emitter');
-var debug = require('debug')('feathers:primus');
-var commons = require('feathers-commons').socket;
-
-module.exports = function(config, configurer) {
- return function() {
- var app = this;
-
- app.enable('feathers primus');
-
- // Monkey patch app.setup(server)
- Proto.mixin({
- service: commons.service,
-
- setup: function(server) {
- if (this.disabled('feathers primus')) {
- return this._super.apply(this, arguments);
- }
-
- debug('Setting up Primus');
-
- var primus = this.primus = new Primus(server, config);
-
- primus.use('emitter', Emitter);
-
- if (typeof configurer === 'function') {
- debug('Calling Primus configuration function');
- configurer.call(this, primus);
- }
-
- var result = this._super.apply(this, arguments);
-
- commons.setup.call(this, {
- method: 'send',
- connection: function() {
- return primus;
- },
- clients: function() {
- return primus;
- },
- params: function(spark) {
- return spark.request.feathers;
- }
- });
-
- return result;
- }
- }, app);
- };
-};
View
51 lib/providers/socket/socketio.js
@@ -1,51 +0,0 @@
-'use strict';
-
-var socketio = require('socket.io');
-var Proto = require('uberproto');
-var debug = require('debug')('feathers:socket.io');
-var commons = require('feathers-commons').socket;
-
-module.exports = function (config) {
- return function () {
- var app = this;
-
- app.enable('feathers socketio');
-
- // Monkey patch app.setup(server)
- Proto.mixin({
- service: commons.service,
-
- setup: function (server) {
- if (this.disabled('feathers socketio')) {
- return this._super.apply(this, arguments);
- }
-
- var io = this.io = socketio.listen(server);
-
- if (typeof config === 'function') {
- debug('Calling SocketIO configuration function');
- config.call(this, io);
- }
-
- var result = this._super.apply(this, arguments);
-
- debug('Setting up SocketIO');
-
- commons.setup.call(this, {
- method: 'emit',
- connection: function() {
- return io.sockets;
- },
- clients: function() {
- return io.sockets.sockets;
- },
- params: function(socket) {
- return socket.feathers;
- }
- });
-
- return result;
- }
- }, app);
- };
-};
View
26 package.json
@@ -27,40 +27,46 @@
"lib": "lib"
},
"scripts": {
- "publish": "git push origin --tags",
+ "prepublish": "npm run compile",
+ "publish": "git push origin && git push origin --tags",
"release:patch": "npm version patch && npm publish",
"release:minor": "npm version minor && npm publish",
"release:major": "npm version major && npm publish",
- "jshint": "jshint lib/. test/. --config",
- "mocha": "mocha test/ --recursive",
+ "compile": "rm -rf lib/ && babel -d lib/ src/",
+ "watch": "babel --watch -d lib/ src/",
+ "jshint": "jshint src/. test/. --config",
"coverage": "istanbul cover _mocha -- test/ --recursive",
- "test": "npm run jshint && npm run coverage"
+ "mocha": "mocha test/ --compilers js:babel-core/register --recursive",
+ "test": "npm run compile && npm run jshint && npm run mocha"
},
"engines": {
"node": ">= 0.10.0",
"npm": ">= 1.3.0"
},
"dependencies": {
+ "babel-polyfill": "^6.3.14",
"debug": "^2.1.1",
"express": "^4.12.3",
"feathers-commons": "^0.3.0",
"feathers-errors": "^1.1.4",
"lodash": "^3.1.0",
- "primus": "^4.0.1",
- "primus-emitter": "^3.0.2",
"rubberduck": "^1.0.0",
- "socket.io": "^1.1.0",
- "uberproto": "^1.1.0"
+ "uberproto": "^1.2.0"
},
"devDependencies": {
+ "babel-cli": "^6.3.17",
+ "babel-core": "^6.3.26",
+ "babel-plugin-add-module-exports": "^0.1.2",
+ "babel-preset-es2015": "^6.3.13",
"body-parser": "^1.13.2",
"feathers-client": "^0.2.1",
+ "feathers-rest": "^1.0.0",
+ "feathers-socketio": "^1.0.0",
"istanbul": "^0.4.0",
"jshint": "^2.6.3",
"mocha": "^2.2.0",
"q": "^1.0.1",
"request": "^2.x",
- "socket.io-client": "^1.0.0",
- "ws": "^0.8.0"
+ "socket.io-client": "^1.0.0"
}
}
View
23 readme.md
@@ -21,18 +21,20 @@ Want to see it in action? Here is a full REST and real-time todo API that uses M
```js
// app.js
-var feathers = require('feathers');
-var mongodb = require('feathers-mongodb');
-var bodyParser = require('body-parser');
-
-var app = feathers();
-var todoService = mongodb({
+import feathers from 'feathers';
+import rest from 'feathers-rest';
+import socketio from 'feathers-socketio';
+import mongodb from 'feathers-mongodb';
+import bodyParser from 'body-parser';
+
+const app = feathers();
+const todoService = mongodb({
db: 'feathers-demo',
collection: 'todos'
});
-app.configure(feathers.rest())
- .configure(feathers.socketio())
+app.configure(rest())
+ .configure(socketio())
.use(bodyParser.json())
.use('/todos', todoService)
.use('/', feathers.static(__dirname))
@@ -42,7 +44,7 @@ app.configure(feathers.rest())
Then run
```
-npm install feathers feathers-mongodb body-parser
+npm install feathers feathers-rest feathers-socketio feathers-mongodb body-parser
node app
```
@@ -56,5 +58,4 @@ Don't want to use MongoDB? Feathers has plugins for [many other databases](http:
## Authors
-- [David Luecke](https://github.com/daffl)
-- [Eric Kryski](http://erickryski.com)
+[Feathers contributors](https://github.com/feathersjs/feathers/graphs/contributors)
View
75 lib/application.js → src/application.js
@@ -1,18 +1,19 @@
-'use strict';
-
-var _ = require('lodash');
-var debug = require('debug')('feathers:application');
-var stripSlashes = require('feathers-commons').stripSlashes;
-var Proto = require('uberproto').extend({
+import _ from 'lodash';
+import makeDebug from 'debug';
+import { stripSlashes } from 'feathers-commons';
+import Uberproto from 'uberproto';
+import mixins from './mixins';
+
+const debug = makeDebug('feathers:application');
+const methods = ['find', 'get', 'create', 'update', 'patch', 'remove'];
+const Proto = Uberproto.extend({
create: null
});
-var mixins = require('./mixins');
-
-module.exports = {
- init: function () {
+export default {
+ init() {
_.extend(this, {
- methods: ['find', 'get', 'create', 'update', 'patch', 'remove'],
+ methods,
mixins: mixins(),
services: {},
providers: [],
@@ -20,35 +21,31 @@ module.exports = {
});
},
- service: function(location, service, options) {
+ service(location, service, options) {
location = stripSlashes(location);
if(!service) {
return this.services[location];
}
- var protoService = Proto.extend(service);
- var self = this;
+ let protoService = Proto.extend(service);
- debug('Registering new service at `' + location + '`');
+ debug(`Registering new service at \`${location}\``);
// Add all the mixins
- _.each(this.mixins, function (fn) {
- fn.call(self, protoService);
- });
+ this.mixins.forEach(fn => fn.call(this, protoService));
if(typeof protoService._setup === 'function') {
protoService._setup(this, location);
}
// Run the provider functions to register the service
- _.each(this.providers, function (provider) {
- provider(location, protoService, options || {});
- });
+ this.providers.forEach(provider =>
+ provider.call(this, location, protoService, options || {}));
// If we ran setup already, set this service up explicitly
if (this._isSetup && typeof protoService.setup === 'function') {
- debug('Setting up service for `' + location + '`');
+ debug(`Setting up service for \`${location}\``);
protoService.setup(this, location);
}
@@ -56,8 +53,8 @@ module.exports = {
return protoService;
},
- use: function (location) {
- var service, middleware = _(arguments)
+ use(location) {
+ let service, middleware = _(arguments)
.slice(1)
.reduce(function (middleware, arg) {
if (typeof arg === 'function') {
@@ -72,33 +69,29 @@ module.exports = {
before: [],
after: []
});
- var hasMethod = function(methods) {
- return _.some(methods, function(name) {
- return (service && typeof service[name] === 'function');
- });
- };
+
+ const hasMethod = methods => _.some(methods, name =>
+ (service && typeof service[name] === 'function'));
// Check for service (any object with at least one service method)
if(hasMethod(['handle', 'set']) || !hasMethod(this.methods)) {
return this._super.apply(this, arguments);
}
- this.service(location, service, {
- // Any arguments left over are other middleware that we want to pass to the providers
- middleware: middleware
- });
+ // Any arguments left over are other middleware that we want to pass to the providers
+ this.service(location, service, { middleware });
return this;
},
- setup: function() {
+ setup() {
// Setup each service (pass the app so that they can look up other services etc.)
- _.each(this.services, function (service, path) {
- debug('Setting up service for `' + path + '`');
+ _.each(this.services, (service, path) => {
+ debug(`Setting up service for \`${path}\``);
if (typeof service.setup === 'function') {
service.setup(this, path);
}
- }.bind(this));
+ });
this._isSetup = true;
@@ -109,16 +102,18 @@ module.exports = {
// That just takes a function in order to keep Feathers plugin configuration easier.
// Environment specific configurations should be done as suggested in the 4.x migration guide:
// https://github.com/visionmedia/express/wiki/Migrating-from-3.x-to-4.x
- configure: function(fn){
+ configure(fn){
fn.call(this);
return this;
},
- listen: function () {
- var server = this._super.apply(this, arguments);
+ listen() {
+ const server = this._super.apply(this, arguments);
+
this.setup(server);
debug('Feathers application listening');
+
return server;
}
};
View
25 src/feathers.js
@@ -0,0 +1,25 @@
+if(!global._babelPolyfill) { require('babel-polyfill'); }
+
+import _ from 'lodash';
+import express from 'express';
+import Proto from 'uberproto';
+import Application from './application';
+
+/**
+ * Create a Feathers application that extends Express.
+ *
+ * @return {Function}
+ * @api public
+ */
+export default function createApplication() {
+ const app = express();
+ Proto.mixin(Application, app);
+ app.init();
+ return app;
+}
+
+// Framework version
+createApplication.version = require('../package.json').version;
+
+// Expose all express methods (like express.engine())
+_.defaults(createApplication, express);
View
57 src/mixins/event.js
@@ -0,0 +1,57 @@
+import _ from 'lodash';
+import rubberduck from 'rubberduck';
+import { EventEmitter } from 'events';
+import { hooks } from 'feathers-commons';
+
+const hookObject = hooks.hookObject;
+const eventMappings = {
+ create: 'created',
+ update: 'updated',
+ remove: 'removed',
+ patch: 'patched'
+};
+
+function upperCase(name) {
+ return name.charAt(0).toUpperCase() + name.substring(1);
+}
+
+export default function(service) {
+ const isEmitter = typeof service.on === 'function' &&
+ typeof service.emit === 'function';
+ const emitter = service._rubberDuck = rubberduck.emitter(service);
+
+ if(typeof service.mixin === 'function' && !isEmitter) {
+ service.mixin(EventEmitter.prototype);
+ }
+
+ service._serviceEvents = _.isArray(service.events) ? service.events.slice() : [];
+
+ // Pass the Rubberduck error event through
+ // TODO deal with error events properly
+ emitter.on('error', function (errors) {
+ service.emit('serviceError', errors[0]);
+ });
+
+ _.each(eventMappings, (event, method) => {
+ const alreadyEmits = service._serviceEvents.indexOf(event) !== -1;
+
+ if (typeof service[method] === 'function' && !alreadyEmits) {
+ // The Rubberduck event name (e.g. afterCreate, afterUpdate or afterDestroy)
+ var eventName = `after${upperCase(method)}`;
+ service._serviceEvents.push(event);
+ // Punch the given method
+ emitter.punch(method, -1);
+ // Pass the event and error event through
+ emitter.on(eventName, function (results, args) {
+ if (!results[0]) { // callback without error
+ const hook = hookObject(method, 'after', args);
+ const data = Array.isArray(results[1]) ? results[1] : [ results[1] ];
+
+ data.forEach(current => service.emit(event, current, hook));
+ } else {
+ service.emit('serviceError', results[0]);
+ }
+ });
+ }
+ });
+}
View
12 lib/mixins/index.js → src/mixins/index.js
@@ -1,9 +1,5 @@
-'use strict';
-
-var _ = require('lodash');
-
-module.exports = function() {
- var mixins = [
+export default function() {
+ const mixins = [
require('./promise'),
require('./event'),
require('./normalizer')
@@ -11,10 +7,10 @@ module.exports = function() {
// Override push to make sure that normalize is always the last
mixins.push = function() {
- var args = [ this.length - 1, 0].concat(_.toArray(arguments));
+ const args = [ this.length - 1, 0].concat(Array.from(arguments));
this.splice.apply(this, args);
return this.length;
};
return mixins;
-};
+}
View
17 src/mixins/normalizer.js
@@ -0,0 +1,17 @@
+import { getArguments } from 'feathers-commons';
+
+export default function (service) {
+ if (typeof service.mixin === 'function') {
+ const mixin = {};
+
+ this.methods.forEach(method => {
+ if(typeof service[method] === 'function') {
+ mixin[method] = function() {
+ return this._super.apply(this, getArguments(method, arguments));
+ };
+ }
+ });
+
+ service.mixin(mixin);
+ }
+}
View
28 src/mixins/promise.js
@@ -0,0 +1,28 @@
+function isPromise(result) {
+ return typeof result !== 'undefined' &&
+ typeof result.then === 'function';
+}
+
+function wrapper() {
+ const result = this._super.apply(this, arguments);
+ const callback = arguments[arguments.length - 1];
+
+ if(typeof callback === 'function' && isPromise(result)) {
+ result.then(data => callback(null, data), error => callback(error));
+ }
+ return result;
+}
+
+export default function (service) {
+ if (typeof service.mixin === 'function') {
+ const mixin = {};
+
+ this.methods.forEach(method => {
+ if(typeof service[method] === 'function') {
+ mixin[method] = wrapper;
+ }
+ });
+
+ service.mixin(mixin);
+ }
+}
View
230 test/application.test.js
@@ -1,36 +1,37 @@
-'use strict';
-
-var assert = require('assert');
-var Proto = require('uberproto');
-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');
+import assert from 'assert';
+import path from 'path';
+import fs from 'fs';
+import Proto from 'uberproto';
+import io from 'socket.io-client';
+import request from 'request';
+import https from 'https';
+import rest from 'feathers-rest';
+import socketio from 'feathers-socketio';
+import feathers from '../src/feathers';
+
+describe('Feathers application', () => {
+ it('is CommonJS compatible', () => {
+ assert.equal(typeof require('../lib/feathers'), 'function');
+ });
-describe('Feathers application', function () {
- it('Express application should use express apps.', function () {
- var app = feathers();
- var child = feathers();
+ it('Express application should use express apps.', () => {
+ const app = feathers();
+ const child = feathers();
app.use('/path', child);
assert.equal(child.parent, app);
});
- it('Register services and look them up with and without leading and trailing slashes.', function () {
- var dummyService = {
- find: function () {
+ it('Register services and look them up with and without leading and trailing slashes.', () => {
+ const dummyService = {
+ find() {
// No need to implement this
}
};
- var app = feathers().use('/dummy/service/', dummyService);
+ const app = feathers().use('/dummy/service/', dummyService);
- app.listen(8012, function(){
- app.use('/another/dummy/service/', dummyService);
- });
+ app.listen(8012, () => app.use('/another/dummy/service/', dummyService));
assert.ok(typeof app.service('dummy/service').find === 'function', 'Could look up without slashes');
assert.ok(typeof app.service('/dummy/service').find === 'function', 'Could look up with leading slash');
@@ -43,28 +44,26 @@ describe('Feathers application', function () {
});
});
- it('Registers a service, wraps it, runs service.setup(), and adds the event mixin.', function (done) {
- var dummyService = {
- setup: function(app, path){
+ it('Registers a service, wraps it, runs service.setup(), and adds the event mixin', done => {
+ const dummyService = {
+ setup(app, path){
this.path = path;
},
- create: function (data, params, callback) {
- callback(null, data);
+ create(data) {
+ return Promise.resolve(data);
}
};
- var dynamicService;
-
- var app = feathers().use('/dummy', dummyService);
- var server = app.listen(7887, function(){
+ const app = feathers().use('/dummy', dummyService);
+ const wrappedService = app.service('dummy');
+ const server = app.listen(7887, function(){
app.use('/dumdum', dummyService);
- dynamicService = app.service('dumdum');
+ const dynamicService = app.service('dumdum');
assert.ok(wrappedService.path === 'dummy', 'Wrapped service setup method ran.');
assert.ok(dynamicService.path === 'dumdum', 'Dynamic service setup method ran.');
});
- var wrappedService = app.service('dummy');
assert.ok(Proto.isPrototypeOf(wrappedService), 'Service got wrapped as Uberproto object');
assert.ok(typeof wrappedService.on === 'function', 'Wrapped service is an event emitter');
@@ -76,15 +75,13 @@ describe('Feathers application', function () {
wrappedService.create({
message: 'Test message'
- }, {}, function (error, data) {
- assert.ok(!error, 'No error');
- assert.equal(data.message, 'Test message', 'Got created event with test message');
- });
+ }).then(data =>
+ assert.equal(data.message, 'Test message', 'Got created event with test message'));
});
- it('Adds REST and SocketIO providers.', function (done) {
- var todoService = {
- get: function (name, params, callback) {
+ it('Initializes REST and SocketIO providers.', function (done) {
+ const todoService = {
+ get(name, params, callback) {
callback(null, {
id: name,
description: 'You have to do ' + name + '!'
@@ -92,16 +89,16 @@ describe('Feathers application', function () {
}
};
- var app = feathers()
- .configure(feathers.rest())
- .configure(feathers.socketio())
+ const app = feathers()
+ .configure(rest())
+ .configure(socketio())
.use('/todo', todoService);
- var server = app.listen(6999).on('listening', function () {
- var socket = io.connect('http://localhost:6999');
+ const server = app.listen(6999).on('listening', () => {
+ const socket = io.connect('http://localhost:6999');
- request('http://localhost:6999/todo/dishes', function (error, response, body) {
+ request('http://localhost:6999/todo/dishes', (error, response, body) => {
assert.ok(response.statusCode === 200, 'Got OK status code');
- var data = JSON.parse(body);
+ const data = JSON.parse(body);
assert.equal(data.description, 'You have to do dishes!');
socket.emit('todo::get', 'laundry', {}, function (error, data) {
@@ -114,19 +111,19 @@ describe('Feathers application', function () {
});
});
- it('Uses custom middleware. (#21)', function (done) {
- var todoService = {
- get: function (name, params, callback) {
- callback(null, {
+ it('Uses custom middleware. (#21)', done => {
+ const todoService = {
+ get(name, params) {
+ return Promise.resolve({
id: name,
- description: 'You have to do ' + name + '!',
+ description: `You have to do ${name}!`,
preService: params.preService
});
}
};
- var app = feathers()
- .configure(feathers.rest())
+ const app = feathers()
+ .configure(rest())
.use('/todo', function (req, res, next) {
req.feathers.preService = 'pre-service middleware';
next();
@@ -136,16 +133,16 @@ describe('Feathers application', function () {
})
.use('/otherTodo', todoService);
- var server = app.listen(6995).on('listening', function () {
- request('http://localhost:6995/todo/dishes', function (error, response, body) {
+ const server = app.listen(6995).on('listening', () => {
+ request('http://localhost:6995/todo/dishes', (error, response, body) => {
assert.ok(response.statusCode === 200, 'Got OK status code');
- var data = JSON.parse(body);
+ const data = JSON.parse(body);
assert.equal(data.preService, 'pre-service middleware', 'Pre-service middleware updated response');
assert.equal(response.headers['post-service'], 'dishes', 'Post-service middleware updated response');
- request('http://localhost:6995/otherTodo/dishes', function (error, response, body) {
+ request('http://localhost:6995/otherTodo/dishes', (error, response, body) => {
assert.ok(response.statusCode === 200, 'Got OK status code');
- var data = JSON.parse(body);
+ const data = JSON.parse(body);
assert.ok(!data.preService && !response.headers['post-service'], 'Custom middleware not run for different service.');
server.close(done);
});
@@ -153,27 +150,27 @@ describe('Feathers application', function () {
});
});
- it('REST and SocketIO with SSL server (#25)', function (done) {
+ it('REST and SocketIO with SSL server (#25)', done => {
// For more info on Reqest HTTPS settings see https://github.com/mikeal/request/issues/418
// This needs to be set so that the SocektIO client can connect
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
- var todoService = {
- get: function (name, params, callback) {
+ const todoService = {
+ get(name, params, callback) {
callback(null, {
id: name,
- description: 'You have to do ' + name + '!'
+ description: `You have to do ${name}!`
});
}
};
- var app = feathers()
- .configure(feathers.rest())
- .configure(feathers.socketio()).use('/secureTodos', todoService);
+ const app = feathers()
+ .configure(rest())
+ .configure(socketio()).use('/secureTodos', todoService);
- var httpsServer = https.createServer({
- key: fs.readFileSync(__dirname + '/resources/privatekey.pem'),
- cert: fs.readFileSync(__dirname + '/resources/certificate.pem'),
+ const httpsServer = https.createServer({
+ key: fs.readFileSync(path.join(__dirname, 'resources', 'privatekey.pem')),
+ cert: fs.readFileSync(path.join(__dirname, 'resources', 'certificate.pem')),
rejectUnauthorized: false,
requestCert: false
}, app).listen(7889);
@@ -181,7 +178,7 @@ describe('Feathers application', function () {
app.setup(httpsServer);
httpsServer.on('listening', function () {
- var socket = io.connect('https://localhost:7889', { secure: true, port: 7889 });
+ const socket = io('https://localhost:7889', { secure: true, port: 7889 });
request({
url: 'https://localhost:7889/secureTodos/dishes',
@@ -189,7 +186,7 @@ describe('Feathers application', function () {
rejectUnhauthorized: false
}, function (error, response, body) {
assert.ok(response.statusCode === 200, 'Got OK status code');
- var data = JSON.parse(body);
+ const data = JSON.parse(body);
assert.equal(data.description, 'You have to do dishes!');
socket.emit('secureTodos::get', 'laundry', {}, function (error, data) {
@@ -204,24 +201,24 @@ describe('Feathers application', function () {
});
it('Returns the value of a promise. (#41)', function (done) {
- var original = {};
- var todoService = {
- get: function (name) {
+ let original = {};
+ const todoService = {
+ get(name) {
original = {
id: name,
q: true,
- description: 'You have to do ' + name + '!'
+ description: `You have to do ${name }!`
};
- return q(original);
+ return Promise.resolve(original);
}
};
- var app = feathers()
- .configure(feathers.rest())
+ const app = feathers()
+ .configure(rest())
.use('/todo', todoService);
- var server = app.listen(6880).on('listening', function () {
- request('http://localhost:6880/todo/dishes', function (error, response, body) {
+ const server = app.listen(6880).on('listening', function () {
+ request('http://localhost:6880/todo/dishes', (error, response, body) => {
assert.ok(response.statusCode === 200, 'Got OK status code');
assert.deepEqual(original, JSON.parse(body));
server.close(done);
@@ -229,28 +226,27 @@ describe('Feathers application', function () {
});
});
- it('Extend params with route params. (#76)', function (done) {
- var todoService = {
- get: function (id, params, callback) {
- var result = {
- id: id,
+ it('Extend params with route params. (#76)', done => {
+ const todoService = {
+ get(id, params) {
+ return Promise.resolve({
+ id,
appId: params.appId
- };
- callback(null, result);
+ });
}
};
- var app = feathers()
- .configure(feathers.rest())
+ const app = feathers()
+ .configure(rest())
.use('/:appId/todo', todoService);
- var expected = {
+ const expected = {
id: 'dishes',
appId: 'theApp'
};
- var server = app.listen(6880).on('listening', function () {
- request('http://localhost:6880/theApp/todo/' + expected.id, function (error, response, body) {
+ const server = app.listen(6880).on('listening', function () {
+ request('http://localhost:6880/theApp/todo/' + expected.id, (error, response, body) => {
assert.ok(response.statusCode === 200, 'Got OK status code');
assert.deepEqual(expected, JSON.parse(body));
server.close(done);
@@ -258,38 +254,36 @@ describe('Feathers application', function () {
});
});
- it('Calls _setup in order to set up custom routes with higher priority. (#86)', function (done) {
- var todoService = {
- get: function (name, params, callback) {
- callback(null, {
+ it('Calls _setup in order to set up custom routes with higher priority. (#86)', done => {
+ const todoService = {
+ get(name) {
+ return Promise.resolve({
id: name,
q: true,
- description: 'You have to do ' + name + '!'
+ description: `You have to do ${name}!`
});
},
- _setup: function (app, path) {
- app.get('/' + path + '/count', function(req, res) {
- res.json({
- counter: 10
- });
+ _setup(app, path) {
+ app.get(`/${path}/count`, function(req, res) {
+ res.json({ counter: 10 });
});
}
};
- var app = feathers()
- .configure(feathers.rest())
+ const app = feathers()
+ .configure(rest())
.use('/todo', todoService);
- var server = app.listen(8999).on('listening', function () {
- request('http://localhost:8999/todo/dishes', function (error, response, body) {
+ const server = app.listen(8999).on('listening', function () {
+ request('http://localhost:8999/todo/dishes', (error, response, body) => {
assert.ok(response.statusCode === 200, 'Got OK status code');
- var data = JSON.parse(body);
+ const data = JSON.parse(body);
assert.equal(data.description, 'You have to do dishes!');
- request('http://localhost:8999/todo/count', function (error, response, body) {
+ request('http://localhost:8999/todo/count', (error, response, body) => {
assert.ok(response.statusCode === 200, 'Got OK status code');
- var data = JSON.parse(body);
+ const data = JSON.parse(body);
assert.equal(data.counter, 10);
server.close(done);
});
@@ -298,27 +292,27 @@ describe('Feathers application', function () {
});
it('mixins are unique to one application', function() {
- var app = feathers();
+ const app = feathers();
app.mixins.push(function() {});
assert.equal(app.mixins.length, 4);
- var otherApp = feathers();
+ const otherApp = feathers();
otherApp.mixins.push(function() {});
assert.equal(otherApp.mixins.length, 4);
});
- it('Event punching happens after normalization (#150)', function (done) {
- var todoService = {
- create: function (data, params, callback) {
- callback(null, data);
+ it('Event punching happens after normalization (#150)', done => {
+ const todoService = {
+ create(data) {
+ return Promise.resolve(data);
}
};
- var app = feathers()
- .configure(feathers.rest())
+ const app = feathers()
+ .configure(rest())
.use('/todo', todoService);
- var server = app.listen(7001).on('listening', function () {
+ const server = app.listen(7001).on('listening', function () {
app.service('todo').create({
test: 'item'
});
View
34 test/distributed.test.js
@@ -1,28 +1,30 @@
-var assert = require('assert');
-var client = require('feathers-client');
-var io = require('socket.io-client');
-var feathers = require('../lib/feathers');
+import assert from 'assert';
+import client from 'feathers-client';
+import io from 'socket.io-client';
+import socketio from 'feathers-socketio';
+import rest from 'feathers-rest';
+import feathers from '../src/feathers';
-describe('Distributed Feathers applications test', function () {
- before(function(done) {
- var app = feathers()
- .configure(feathers.socketio())
+describe('Distributed Feathers applications test', () => {
+ before(done => {
+ const app = feathers()
+ .configure(socketio())
.use('todos', {
- create: function(data, params, callback) {
+ create(data) {
data.id = 42;
- callback(null, data);
+ return Promise.resolve(data);
}
});
app.listen(8888, done);
});
- it('passes created event between servers', function (done) {
- var socket = io('http://localhost:8888');
- var remoteApp = client().configure(client.socketio(socket));
- var todo = { text: 'Created on alpha server', complete: false };
- var beta = feathers()
- .configure(feathers.rest())
+ it('passes created event between servers', done => {
+ const socket = io('http://localhost:8888');
+ const remoteApp = client().configure(client.socketio(socket));
+ const todo = { text: 'Created on alpha server', complete: false };
+ const beta = feathers()
+ .configure(rest())
.use('todos', remoteApp.service('todos'));
beta.listen(9999, function() {
View
107 test/mixins/event.test.js
@@ -1,18 +1,16 @@
-'use strict';
-
-var assert = require('assert');
-var _ = require('lodash');
-var Proto = require('uberproto');
-var EventEmitter = require('events').EventEmitter;
-
-var mixinEvent = require('../../lib/mixins/event');
-var create = Proto.create;
-
-describe('Event mixin', function () {
- it('initializes', function () {
- var FixtureService = Proto.extend({
- setup: function (arg) {
- return 'Original setup: ' + arg;
+import assert from 'assert';
+import _ from 'lodash';
+import Proto from 'uberproto';
+import { EventEmitter } from 'events';
+import mixinEvent from '../../lib/mixins/event';
+
+const create = Proto.create;
+
+describe('Event mixin', () => {
+ it('initializes', () => {
+ const FixtureService = Proto.extend({
+ setup(arg) {
+ return `Original setup: ${arg}`;
}
});
@@ -22,13 +20,13 @@ describe('Event mixin', function () {
assert.equal(typeof FixtureService.on, 'function');
assert.equal(typeof FixtureService.emit, 'function');
- var instance = create.call(FixtureService);
+ const instance = create.call(FixtureService);
assert.equal('Original setup: Test', instance.setup('Test'));
assert.ok(instance._rubberDuck instanceof EventEmitter);
- var existingMethodsService = {
- setup: function (arg) {
- return 'Original setup from object: ' + arg;
+ const existingMethodsService = {
+ setup(arg) {
+ return `Original setup from object: ${arg}`;
}
};
@@ -40,14 +38,12 @@ describe('Event mixin', function () {
it('serviceError', function (done) {
var FixtureService = Proto.extend({
- create: function (data, params, cb) {
- _.defer(function () {
- cb(new Error('Something went wrong'));
- });
+ create(data, params, cb) {
+ cb(new Error('Something went wrong'));
}
});
- var instance = create.call(FixtureService);
+ const instance = create.call(FixtureService);
mixinEvent(instance);
@@ -57,26 +53,21 @@ describe('Event mixin', function () {
done();
});
- instance.create({
- name: 'Tester'
- }, {}, function (error) {
- assert.ok(error instanceof Error);
- });
+ instance.create({ name: 'Tester' }, {},
+ error => assert.ok(error instanceof Error));
});
- it('created', function (done) {
- var FixtureService = Proto.extend({
- create: function (data, params, cb) {
- _.defer(function () {
- cb(null, {
- id: 10,
- name: data.name
- });
+ it('created', done => {
+ const FixtureService = Proto.extend({
+ create: function (data, params, callback) {
+ callback(null, {
+ id: 10,
+ name: data.name
});
}
});
- var instance = create.call(FixtureService);
+ const instance = create.call(FixtureService);
mixinEvent(instance);
@@ -92,14 +83,12 @@ describe('Event mixin', function () {
name: 'Tester'
}, {
custom: 'value'
- }, function (error, data) {
- assert.equal(data.id, 10);
- });
+ }, (error, data) => assert.equal(data.id, 10));
});
- it('updated', function (done) {
- var FixtureService = Proto.extend({
- update: function (id, data, params, cb) {
+ it('updated', done => {
+ const FixtureService = Proto.extend({
+ update(id, data, params, cb) {
_.defer(function () {
cb(null, {
id: id,
@@ -109,7 +98,7 @@ describe('Event mixin', function () {
}
});
- var instance = create.call(FixtureService);
+ const instance = create.call(FixtureService);
mixinEvent(instance);
@@ -131,9 +120,9 @@ describe('Event mixin', function () {
});
});
- it('removed', function (done) {
- var FixtureService = Proto.extend({
- remove: function (id, params, cb) {
+ it('removed', done => {
+ const FixtureService = Proto.extend({
+ remove(id, params, cb) {
_.defer(function () {
cb(null, {
id: id
@@ -142,7 +131,7 @@ describe('Event mixin', function () {
}
});
- var instance = create.call(FixtureService);
+ const instance = create.call(FixtureService);
mixinEvent(instance);
@@ -160,22 +149,22 @@ describe('Event mixin', function () {
});
});
- it('array event data emits multiple event', function (done) {
- var fixture = [
+ it('array event data emits multiple event', done => {
+ const fixture = [
{ id: 0 },
{ id: 1 },
{ id: 2 },
];
- var FixtureService = Proto.extend({
- create: function (data, params, cb) {
+ const FixtureService = Proto.extend({
+ create(data, params, cb) {
_.defer(function () {
cb(null, fixture);
});
}
});
- var instance = create.call(FixtureService);
- var counter = 0;
+ const instance = create.call(FixtureService);
+ let counter = 0;
mixinEvent(instance);
@@ -190,10 +179,10 @@ describe('Event mixin', function () {
instance.create({}, {}, function () {});
});
- it('does not punch when service has an events list (#118)', function(done) {
- var FixtureService = Proto.extend({
+ it('does not punch when service has an events list (#118)', done => {
+ const FixtureService = Proto.extend({
events: [ 'created' ],
- create: function (data, params, cb) {
+ create(data, params, cb) {
_.defer(function () {
cb(null, {
id: 10,
@@ -205,7 +194,7 @@ describe('Event mixin', function () {
FixtureService.mixin(EventEmitter.prototype);
- var instance = create.call(FixtureService);
+ const instance = create.call(FixtureService);
mixinEvent(instance);
View
42 test/mixins/normalizer.test.js
@@ -1,14 +1,12 @@
-'use strict';
+import assert from 'assert';
+import Proto from 'uberproto';
+import normalizer from '../../lib/mixins/normalizer';
+import mixins from '../../lib/mixins';
-var assert = require('assert');
-var Proto = require('uberproto');
-var normalizer = require('../../lib/mixins/normalizer');
-var mixins = require('../../lib/mixins');
-
-describe('Argument normalizer mixin', function () {
- it('normalizer mixin is always the last to run', function() {
- var arr = mixins();
- var dummy = function() { };
+describe('Argument normalizer mixin', () => {
+ it('normalizer mixin is always the last to run', () => {
+ const arr = mixins();
+ const dummy = function() { };
assert.equal(arr.length, 3);
@@ -21,12 +19,10 @@ describe('Argument normalizer mixin', function () {
// The normalization is already tests in all variations in `getArguments`
// so we just so we only test two random samples
- it('normalizes .find without a callback', function (done) {
- var context = {
- methods: ['find']
- };
- var FixtureService = Proto.extend({
- find: function(params, callback) {
+ it('normalizes .find without a callback', done => {
+ const context = { methods: ['find'] };
+ const FixtureService = Proto.extend({
+ find(params, callback) {
assert.ok(typeof callback === 'function');
assert.equal(params.test, 'Here');
done();
@@ -35,17 +31,15 @@ describe('Argument normalizer mixin', function () {
normalizer.call(context, FixtureService);
- var instance = Proto.create.call(FixtureService);
+ const instance = Proto.create.call(FixtureService);
instance.find({ test: 'Here' });
});
- it('normalizes .update without params and callback', function (done) {
- var context = {
- methods: ['update']
- };
- var FixtureService = Proto.extend({
- update: function(id, data, params, callback) {
+ it('normalizes .update without params and callback', done => {
+ const context = { methods: ['update'] };
+ const FixtureService = Proto.extend({
+ update(id, data, params, callback) {
assert.equal(id, 1);
assert.ok(typeof callback === 'function');
assert.deepEqual(data, { test: 'Here' });
@@ -56,7 +50,7 @@ describe('Argument normalizer mixin', function () {
normalizer.call(context, FixtureService);
- var instance = Proto.create.call(FixtureService);
+ const instance = Proto.create.call(FixtureService);
instance.update(1, { test: 'Here' });
});
View
60 test/mixins/promise.test.js
@@ -1,31 +1,25 @@
-'use strict';
+import assert from 'assert';
+import Proto from 'uberproto';
+import mixin from '../../lib/mixins/promise';
-var assert = require('assert');
-var Proto = require('uberproto');
-var create = Proto.create;
-var q = require('q');
-var _ = require('lodash');
+const create = Proto.create;
-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) {
+describe('Promises/A+ mixin', () => {
+ it('Calls a callback when a promise is returned from the original service', done => {
// A dummy context (this will normally be the application)
- var context = {
- methods: ['get']
- };
- var FixtureService = Proto.extend({
+ const context = { methods: ['get'] };
+ const FixtureService = Proto.extend({
get: function (id) {
- return q({
+ return Promise.resolve({
id: id,
- description: 'You have to do ' + id
+ description: `You have to do ${id}`
});
}
});
mixin.call(context, FixtureService);
- var instance = create.call(FixtureService);
+ const instance = create.call(FixtureService);
instance.get('dishes', {}, function (error, data) {
assert.deepEqual(data, {
id: 'dishes',
@@ -35,20 +29,14 @@ describe('Promises/A+ mixin', function () {
});
});
- it('calls back with an error for a failing deferred', function(done) {
+ it('calls back with an error for a failing deferred', 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;
+ return Promise.reject(new Error('Something went wrong'));
}
});
@@ -64,29 +52,21 @@ describe('Promises/A+ mixin', function () {
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;
+ const context = { methods: ['create'] };
+ const FixtureService = Proto.extend({
+ create(data) {
+ return Promise.resolve(data);
}
});
- var original = {
+ const original = {
id: 'laundry',
description: 'You have to do laundry'
};
mixin.call(context, FixtureService);
- var instance = create.call(FixtureService);
- instance.create(original, {}).then(function(data) {
+ const instance = create.call(FixtureService);
+ instance.create(original, {}).then(data => {
assert.deepEqual(data, original);
done();
});
View
552 test/providers/primus.test.js
@@ -1,552 +0,0 @@
-'use strict';
-
-var assert = require('assert');
-var _ = require('lodash');
-
-var feathers = require('../../lib/feathers');
-var fixture = require('./service-fixture');
-var todoService = fixture.Service;
-var verify = fixture.verify;
-
-describe('Primus provider', function () {
- var server, socket, app,
- socketParams = {
- user: { name: 'David' },
- provider: 'websockets'
- };
-
- before(function () {
- app = feathers()
- .configure(feathers.primus({
- transformer: 'websockets'
- }, function(primus) {
- socket = new primus.Socket('http://localhost:7888');
-
- primus.authorize(function (req, done) {
- req.feathers = socketParams;
- done();
- });
- }))
- .use('todo', todoService);
-
- server = app.listen(7888, function(){
- app.use('tasks', todoService);
- });
- });
-
- after(function (done) {
- socket.socket.close();
- server.close(done);
- });
-
- it('runs primus before setup (#131)', function(done) {
- var counter = 0;
- var app = feathers()
- .configure(feathers.primus({
- transformer: 'websockets'
- }, function() {
- assert.equal(counter, 0);
- counter++;
- }))
- .use('/todos', {
- find: function(params, callback) {
- callback(null, []);
- },
- setup: function(app) {
- assert.ok(app.primus);
- assert.equal(counter, 1, 'SocketIO configuration ran first');
- }
- });
-
- var srv = app.listen(9119);
- srv.on('listening', function() {
- srv.close(done);
- });
- });
-
- it('Passes handshake as service parameters.', function(done) {
- var service = app.service('todo');
- var old = {
- find: service.find,
- create: service.create,
- update: service.update,
- remove: service.remove
- };
-
- service.find = function(params) {
- assert.deepEqual(_.omit(params, 'query'), socketParams, 'Handshake parameters passed on proper position');
- old.find.apply(this, arguments);
- };
-
- service.create = function(data, params) {
- assert.deepEqual(_.omit(params, 'query'), socketParams, 'Passed handshake parameters');
- old.create.apply(this, arguments);
- };
-
- service.update = function(id, data, params) {
- assert.deepEqual(params, _.extend({
- query: {
- test: 'param'
- }
- }, socketParams), 'Passed handshake parameters as query');
- old.update.apply(this, arguments);
- };
-
- socket.send('todo::create', {}, {}, function () {
- socket.send('todo::update', 1, {}, { test: 'param' }, function() {
- _.extend(service, old);
- done();
- });
- });
- });
-
- it('Missing parameters in socket call works. (#88)', function(done) {
- var service = app.service('todo');
- var old = {
- find: service.find
- };
-
- service.find = function(params) {
- assert.deepEqual(_.omit(params, 'query'), socketParams, 'Handshake parameters passed on proper position');
- old.find.apply(this, arguments);
- };
-
- socket.send('todo::find', function () {
- _.extend(service, old);
- done();
- });
- });
-
- describe('Services', function() {
- it('invalid arguments cause an error', function (done) {
- socket.send('todo::find', 1, {}, function(error) {
- assert.equal(error.message, 'Too many arguments for \'find\' service method');
- done();
- });
- });
-
- describe('CRUD', function () {
-
- it('::find', function (done) {
- socket.send('todo::find', {}, function (error, data) {
- verify.find(data);
-
- done(error);
- });
- });
-
- it('::get', function (done) {
- socket.send('todo::get', 'laundry', {}, function (error, data) {
- verify.get('laundry', data);
-
- done(error);
- });
- });
-
- it('::create', function (done) {
- var original = {
- name: 'creating'
- };
-
- socket.send('todo::create', original, {}, function (error, data) {
- verify.create(original, data);
-
- done(error);
- });
- });
-
- it('::create without parameters and callback', function (done) {
- var original = {
- name: 'creating'
- };
-
- socket.send('todo::create', original);
-
- socket.once('todo created', function(data) {
- verify.create(original, data);
-
- done();
- });
- });
-
- it('::update', function (done) {
- var original = {
- name: 'updating'
- };
-
- socket.send('todo::update', 23, original, {}, function (error, data) {
- verify.update(23, original, data);
-
- done(error);
- });
- });
-
- it('::update many', function (done) {
- var original = {
- name: 'updating',
- many: true
- };
-
- socket.send('todo::update', null, original, {}, function (error, data) {
- verify.update(null, original, data);
-
- done(error);
- });
- });
-
- it('::patch', function (done) {
- var original = {
- name: 'patching'
- };
-
- socket.send('todo::patch', 25, original, {}, function (error, data) {
- verify.patch(25, original, data);
-
- done(error);
- });
- });
-
- it('::patch many', function (done) {
- var original = {
- name: 'patching',
- many: true
- };
-
- socket.send('todo::patch', null, original, {}, function (error, data) {
- verify.patch(null, original, data);
-
- done(error);
- });
- });
-
- it('::remove', function (done) {
- socket.send('todo::remove', 11, {}, function (error, data) {
- verify.remove(11, data);
-
- done(error);
- });
- });
-
- it('::remove many', function (done) {
- socket.send('todo::remove', null, {}, function (error, data) {
- verify.remove(null, data);
-
- done(error);
- });
- });
- });
-
- describe('Events', function () {
- it('created', function (done) {
- var original = {
- name: 'created event'
- };
-
- socket.once('todo created', function (data) {
- verify.create(original, data);
- done();
- });
-
- socket.send('todo::create', original, {}, function () {});
- });
-
- it('updated', function (done) {
- var original = {
- name: 'updated event'
- };
-
- socket.once('todo updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.send('todo::update', 10, original, {}, function () {});
- });
-
- it('patched', function(done) {
- var original = {
- name: 'patched event'
- };
-
- socket.once('todo patched', function (data) {
- verify.patch(12, original, data);
- done();
- });
-
- socket.send('todo::patch', 12, original, {}, function () {});
- });
-
- it('removed', function (done) {
- socket.once('todo removed', function (data) {
- verify.remove(333, data);
- done();
- });
-
- socket.send('todo::remove', 333, {}, function () {});
- });
- });
-
- describe('Event filtering', function() {
- it('.created', function (done) {
- var service = app.service('todo');
- var original = { description: 'created event test' };
- var oldCreated = service.created;
-
- service.created = function(data, params, callback) {
- assert.ok(service === this);
- assert.deepEqual(params, socketParams);
- verify.create(original, data);
-
- callback(null, _.extend({ processed: true }, data));
- };
-
- socket.send('todo::create', original, {}, function() {});
-
- socket.once('todo created', function (data) {
- service.created = oldCreated;
- // Make sure Todo got processed
- verify.create(_.extend({ processed: true }, original), data);
- done();
- });
- });
-
- it('.updated', function (done) {
- // TODO this is not testing the right thing
- // but we will get better event filtering in v2 anyway
- var original = {
- name: 'updated event'
- };
-
- socket.once('todo updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.send('todo::update', 10, original, {}, function () {});
- });
-
- it('.removed', function (done) {
- var service = app.service('todo');
- var oldRemoved = service.removed;
-
- service.removed = function(data, params, callback) {
- assert.ok(service === this);
- assert.deepEqual(params, socketParams);
-
- if(data.id === 23) {
- // Only dispatch with given id
- return callback(null, data);
- }
-
- callback(null, false);
- };
-
- socket.send('todo::remove', 1, {}, function() {});
- socket.send('todo::remove', 23, {}, function() {});
-
- socket.on('todo removed', function (data) {
- service.removed = oldRemoved;
- assert.equal(data.id, 23);
- done();
- });
- });
- });
- });
-
- describe('Dynamic services', function() {
- describe('CRUD', function () {
- it('::find', function (done) {
- socket.send('tasks::find', {}, function (error, data) {
- verify.find(data);
-
- done(error);
- });
- });
-
- it('::get', function (done) {
- socket.send('tasks::get', 'laundry', {}, function (error, data) {
- verify.get('laundry', data);
-
- done(error);
- });
- });
-
- it('::create', function (done) {
- var original = {
- name: 'creating'
- };
-
- socket.send('tasks::create', original, {}, function (error, data) {
- verify.create(original, data);
-
- done(error);
- });
- });
-
- it('::update', function (done) {
- var original = {
- name: 'updating'
- };
-
- socket.send('tasks::update', 23, original, {}, function (error, data) {
- verify.update(23, original, data);
-
- done(error);
- });
- });
-
- it('::patch', function (done) {
- var original = {
- name: 'patching'
- };
-
- socket.send('tasks::patch', 25, original, {}, function (error, data) {
- verify.patch(25, original, data);
-
- done(error);
- });
- });
-
- it('::remove', function (done) {
- socket.send('tasks::remove', 11, {}, function (error, data) {
- verify.remove(11, data);
-
- done(error);
- });
- });
- });
-
- describe('Events', function () {
- it('created', function (done) {
- var original = {
- name: 'created event'
- };
-
- socket.once('tasks created', function (data) {
- verify.create(original, data);
- done();
- });
-
- socket.send('tasks::create', original, {}, function () {});
- });
-
- it('updated', function (done) {
- var original = {
- name: 'updated event'
- };
-
- socket.once('tasks updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.send('tasks::update', 10, original, {}, function () {});
- });
-
- it('patched', function(done) {
- var original = {
- name: 'patched event'
- };
-
- socket.once('tasks patched', function (data) {
- verify.patch(12, original, data);
- done();
- });
-
- socket.send('tasks::patch', 12, original, {}, function () {});
- });
-
- it('removed', function (done) {
- socket.once('tasks removed', function (data) {
- verify.remove(333, data);
- done();
- });
-
- socket.send('tasks::remove', 333, {}, function () {});
- });
-
- it('custom events', function(done) {
- var service = app.service('todo');
- var original = {
- name: 'created event'
- };
- var old = service.create;
-
- service.create = function(data) {
- this.emit('log', { message: 'Custom log event', data: data });
- service.create = old;
- return old.apply(this, arguments);
- };
-
- socket.once('todo log', function(data) {
- assert.deepEqual(data, { message: 'Custom log event', data: original });
- done();
- });
-
- socket.send('todo::create', original, {}, function () {});
- });
- });
-
- describe('Event filtering', function() {
- it('.created', function (done) {
- var service = app.service('tasks');
- var original = { description: 'created event test' };
- var oldCreated = service.created;
-
- service.created = function(data, params, callback) {
- assert.deepEqual(params, socketParams);
- verify.create(original, data);
-
- callback(null, _.extend({ processed: true }, data));
- };
-
- socket.send('tasks::create', original, {}, function() {});
-
- socket.once('tasks created', function (data) {
- service.created = oldCreated;
- // Make sure Todo got processed
- verify.create(_.extend({ processed: true }, original), data);
- done();
- });
- });
-
- it('.updated', function (done) {
- var original = {
- name: 'updated event'
- };
-
- socket.once('tasks updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.send('tasks::update', 10, original, {}, function () {});
- });
-
- it('.removed', function (done) {
- var service = app.service('tasks');
- var oldRemoved = service.removed;
-
- service.removed = function(data, params, callback) {
- assert.deepEqual(params, socketParams);
-
- if(data.id === 23) {
- // Only dispatch with given id
- return callback(null, data);
- }
-
- callback(null, false);
- };
-
- socket.send('tasks::remove', 1, {}, function() {});
- socket.send('tasks::remove', 23, {}, function() {});
-
- socket.on('tasks removed', function (data) {
- service.removed = oldRemoved;
- assert.equal(data.id, 23);
- done();
- });
- });
- });
- });
-});
View
418 test/providers/rest.test.js
@@ -1,418 +0,0 @@
-'use strict';
-
-var request = require('request');
-var assert = require('assert');
-var feathers = require('../../lib/feathers');
-var bodyParser = require('body-parser');
-
-var fixture = require('./service-fixture');
-var todoService = fixture.Service;
-var verify = fixture.verify;
-
-describe('REST provider', function () {
- describe('CRUD', function () {
- var server, app;
-
- before(function () {
- app = feathers().configure(feathers.rest())
- .use(bodyParser.json())
- .use('codes', {
- get: function(id, params, callback) {
- callback();
- },
-
- create: function(data, params, callback) {
- callback(null, data);
- }
- })
- .use('todo', todoService);
-
- server = app.listen(4777, function(){
- app.use('tasks', todoService);
- });
- });
-
- after(function (done) {
- server.close(done);
- });
-
- describe('Services', function() {
-
- it('GET .find', function (done) {
- request('http://localhost:4777/todo', function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.find(JSON.parse(body));
- done(error);
- });
- });
-
- it('GET .get', function (done) {
- request('http://localhost:4777/todo/dishes', function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.get('dishes', JSON.parse(body));
- done(error);
- });
- });
-
- it('POST .create', function (done) {
- var original = {
- description: 'POST .create'
- };
-
- request({
- url: 'http://localhost:4777/todo',
- method: 'post',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- assert.ok(response.statusCode === 201, 'Got CREATED status code');
- verify.create(original, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('PUT .update', function (done) {
- var original = {
- description: 'PUT .update'
- };
-
- request({
- url: 'http://localhost:4777/todo/544',
- method: 'put',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.update(544, original, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('PUT .update many', function (done) {
- var original = {
- description: 'PUT .update',
- many: true
- };
-
- request({
- url: 'http://localhost:4777/todo',
- method: 'put',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- var data = JSON.parse(body);
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.update(null, original, data);
-
- done(error);
- });
- });
-
- it('PATCH .patch', function (done) {
- var original = {
- description: 'PATCH .patch'
- };
-
- request({
- url: 'http://localhost:4777/todo/544',
- method: 'patch',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.patch(544, original, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('PATCH .patch many', function (done) {
- var original = {
- description: 'PATCH .patch',
- many: true
- };
-
- request({
- url: 'http://localhost:4777/todo',
- method: 'patch',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.patch(null, original, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('DELETE .remove', function (done) {
- request({
- url: 'http://localhost:4777/tasks/233',
- method: 'delete'
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.remove(233, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('DELETE .remove many', function (done) {
- request({
- url: 'http://localhost:4777/tasks',
- method: 'delete'
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.remove(null, JSON.parse(body));
-
- done(error);
- });
- });
- });
-
- describe('Dynamic Services', function() {
- it('GET .find', function (done) {
- request('http://localhost:4777/tasks', function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.find(JSON.parse(body));
- done(error);
- });
- });
-
- it('GET .get', function (done) {
- request('http://localhost:4777/tasks/dishes', function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.get('dishes', JSON.parse(body));
- done(error);
- });
- });
-
- it('POST .create', function (done) {
- var original = {
- description: 'Dynamic POST .create'
- };
-
- request({
- url: 'http://localhost:4777/tasks',
- method: 'post',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- assert.ok(response.statusCode === 201, 'Got CREATED status code');
- verify.create(original, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('PUT .update', function (done) {
- var original = {
- description: 'Dynamic PUT .update'
- };
-
- request({
- url: 'http://localhost:4777/tasks/544',
- method: 'put',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.update(544, original, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('PATCH .patch', function (done) {
- var original = {
- description: 'Dynamic PATCH .patch'
- };
-
- request({
- url: 'http://localhost:4777/tasks/544',
- method: 'patch',
- body: JSON.stringify(original),
- headers: {
- 'Content-Type': 'application/json'
- }
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.patch(544, original, JSON.parse(body));
-
- done(error);
- });
- });
-
- it('DELETE .remove', function (done) {
- request({
- url: 'http://localhost:4777/tasks/233',
- method: 'delete'
- }, function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code');
- verify.remove(233, JSON.parse(body));
-
- done(error);
- });
- });
- });
- });
-
- describe('HTTP status codes', function() {
- var app;
- var server;
-
- before(function() {
- app = feathers().configure(feathers.rest()).use('todo', {
- get: function (id, params, callback) {
- callback(null, { description: 'You have to do ' + id });
- },
-
- find: function(params, callback) {
- callback();
- }
- });
-
- /* jshint ignore:start */
- // Error handler
- app.use(function (error, req, res, next) {
- assert.equal(error.message, 'Method `create` is not supported by this endpoint.');
- res.json({ message: error.message });
- });
- /* jshint ignore:end */
-
- server = app.listen(4780);
- });
-
- after(function(done) {
- server.close(done);
- });
-
- it('throws a 405 for undefined service methods (#99)', function (done) {
- request('http://localhost:4780/todo/dishes', function (error, response, body) {
- assert.ok(response.statusCode === 200, 'Got OK status code for .get');
- assert.deepEqual(JSON.parse(body), { description: 'You have to do dishes' }, 'Got expected object');
- request({
- method: 'post',
- url: 'http://localhost:4780/todo'
- }, function (error, response, body) {
- assert.ok(response.statusCode === 405, 'Got 405 for .create');
- assert.deepEqual(JSON.parse(body), { message: 'Method `create` is not supported by this endpoint.' }, 'Error serialized as expected');
- done();
- });
- });
- });
-
- it('throws a 404 for undefined route', function(done) {
- request('http://localhost:4780/todo/foo/bar', function (error, response) {
- assert.ok(response.statusCode === 404, 'Got Not Found code');
-
- done(error);
- });
- });
-
- it('empty response sets 204 status codes', function(done) {
- request('http://localhost:4780/todo', function (error, response) {
- assert.ok(response.statusCode === 204, 'Got empty status code');
-
- done(error);
- });
- });
- });
-
- it('sets service parameters', function (done) {
- var service = {
- get: function (id, params, callback) {
- callback(null, params);
- }
- };
-
- var server = feathers().configure(feathers.rest())
- .use(function (req, res, next) {
- assert.ok(req.feathers, 'Feathers object initialized');
- req.feathers.test = 'Happy';
- next();
- })
- .use('service', service)
- .listen(4778);
-
- request('http://localhost:4778/service/bla?some=param&another=thing', function (error, response, body) {
- var expected = {
- test: 'Happy',
- query: {
- some: 'param',
- another: 'thing'
- }
- };
-
- assert.ok(response.statusCode === 200, 'Got OK status code');
- assert.deepEqual(JSON.parse(body), expected, 'Got params object back');
- server.close(done);
- });
- });
-
- it('disables REST and lets you set the handler manually', function(done) {
- var app = feathers({ rest: false });
-
- app.configure(feathers.rest(function restFormatter(req, res) {
- res.format({
- 'text/plain': function() {
- res.end('The todo is: ' + res.data.description);
- }
- });
- }))
- .use('/todo', {
- get: function (id, params, callback) {
- callback(null, { description: 'You have to do ' + id });
- }
- });
-
- var server = app.listen(4776);
- request('http://localhost:4776/todo/dishes', function (error, response, body) {
- assert.equal(body, 'The todo is: You have to do dishes');
- server.close(done);
- });
- });
-
- it('Lets you configure your own middleware before the handler (#40)', function(done) {
- var data = { description: 'Do dishes!', id: 'dishes' };
- var app = feathers();
-
- app.use(function defaultContentTypeMiddleware (req, res, next) {
- req.headers['content-type'] = req.headers['content-type'] || 'application/json';
- next();
- })
- .configure(feathers.rest())
- .use(bodyParser.json())
- .use('/todo', {
- create: function (data, params, callback) {
- callback(null, data);
- }
- });
-
- var server = app.listen(4775);
- request({
- method: 'POST',
- url: 'http://localhost:4775/todo',
- body: JSON.stringify(data)
- }, function (error, response, body) {
- assert.deepEqual(JSON.parse(body), data);
- server.close(done);
- });
- });
-});
View
112 test/providers/service-fixture.js
@@ -1,112 +0,0 @@
-'use strict';
-
-var _ = require('lodash');
-var assert = require('assert');
-
-var findAllData = [{
- id: 0,
- description: 'You have to do something'
-}, {
- id: 1,
- description: 'You have to do laundry'
-}];
-
-exports.Service = {
- events: [ 'log' ],
-
- find: function (params, callback) {
- callback(null, findAllData);
- },
-
- get: function (name, params, callback) {
- callback(null, {
- id: name,
- description: "You have to do " + name + "!"
- });
- },
-
- create: function (data, params, callback) {
- var result = _.clone(data);
- result.id = 42;
- result.status = 'created';
-
- if(Array.isArray(data)) {
- result.many = true;
- }
-
- callback(null, result);
- },
-
- update: function (id, data, params, callback) {
- var result = _.clone(data);
- result.id = id;
- result.status = 'updated';
-
- if(id === null) {
- result.many = true;
- }
-
- callback(null, result);
- },
-
- patch: function (id, data, params, callback) {
- var result = _.clone(data);
- result.id = id;
- result.status = 'patched';
-
- if(id === null) {
- result.many = true;
- }
-
- callback(null, result);
- },
-
- remove: function (id, params, callback) {
- var result = {
- id: id
- };
-
- callback(null, result);
- }
-};
-
-exports.verify = {
- find: function (data) {
- assert.deepEqual(findAllData, data, 'Data as expected');
- },
-
- get: function (id, data) {
- assert.equal(data.id, id, 'Got id in data');
- assert.equal(data.description, 'You have to do ' + id + '!', 'Got description');
- },
-
- create: function (original, current) {
- var expected = _.extend({}, original, {
- id: 42,
- status: 'created'
- });
- assert.deepEqual(expected, current, 'Data ran through .create as expected');
- },
-
- update: function (id, original, current) {
- var expected = _.extend({}, original, {
- id: id,
- status: 'updated'
- });
- assert.deepEqual(expected, current, 'Data ran through .update as expected');
- },
-
- patch: function (id, original, current) {
- var expected = _.extend({}, original, {
- id: id,
- status: 'patched'
- });
- assert.deepEqual(expected, current, 'Data ran through .patch as expected');
- },
-
- remove: function (id, data) {
- assert.deepEqual({
- id: id
- }, data, '.remove called');
- }
-};
View
548 test/providers/socketio.test.js
@@ -1,548 +0,0 @@
-'use strict';
-
-var _ = require('lodash');
-var feathers = require('../../lib/feathers');
-var io = require('socket.io-client');
-var assert = require('assert');
-
-var fixture = require('./service-fixture');
-var todoService = fixture.Service;
-var verify = fixture.verify;
-
-describe('SocketIO provider', function () {
- var server, socket, app,
- socketParams = {
- user: { name: 'David' },
- provider: 'socketio'
- };
-
- before(function () {
- app = feathers()
- .configure(feathers.socketio(function(io) {
- io.use(function (socket, next) {
- socket.feathers = socketParams;
- next();
- });
- }))
- .use('todo', todoService);
-
- server = app.listen(7886, function(){
- app.use('tasks', todoService);
- });
-
- socket = io.connect('http://localhost:7886');
- });
-
- after(function (done) {
- socket.disconnect();
- server.close(done);
- });
-
- it('runs io before setup (#131)', function(done) {
- var counter = 0;
- var app = feathers()
- .configure(feathers.socketio(function() {
- assert.equal(counter, 0);
- counter++;
- }))
- .use('/todos', {
- find: function(params, callback) {
- callback(null, []);
- },
- setup: function(app) {
- assert.ok(app.io);
- assert.equal(counter, 1, 'SocketIO configuration ran first');
- }
- });
-
- var srv = app.listen(8887);
- srv.on('listening', function() {
- srv.close(done);
- });
- });
-
- it('passes handshake as service parameters', function(done) {
- var service = app.service('todo');
- var old = {
- find: service.find,
- create: service.create,
- update: service.update,
- remove: service.remove
- };
-
- service.find = function(params) {
- assert.deepEqual(_.omit(params, 'query'), socketParams, 'Handshake parameters passed on proper position');
- old.find.apply(this, arguments);
- };
-
- service.create = function(data, params) {
- assert.deepEqual(_.omit(params, 'query'), socketParams, 'Passed handshake parameters');
- old.create.apply(this, arguments);
- };
-
- service.update = function(id, data, params) {
- assert.deepEqual(params, _.extend({
- query: {
- test: 'param'
- }
- }, socketParams), 'Passed handshake parameters as query');
- old.update.apply(this, arguments);
- };
-
- socket.emit('todo::create', {}, {}, function () {
- socket.emit('todo::update', 1, {}, { test: 'param' }, function() {
- _.extend(service, old);
- done();
- });
- });
- });
-
- it('missing parameters in socket call works (#88)', function(done) {
- var service = app.service('todo');
- var old = {
- find: service.find
- };
-
- service.find = function(params) {
- assert.deepEqual(_.omit(params, 'query'), socketParams, 'Handshake parameters passed on proper position');
- old.find.apply(this, arguments);
- };
-
- socket.emit('todo::find', function () {
- _.extend(service, old);
- done();
- });
- });
-
- describe('Services', function() {
- it('invalid arguments cause an error', function (done) {
- socket.emit('todo::find', 1, {}, function(error) {
- assert.equal(error.message, 'Too many arguments for \'find\' service method');
- done();
- });
- });
-
- describe('CRUD', function () {
- it('::find', function (done) {
- socket.emit('todo::find', {}, function (error, data) {
- verify.find(data);
-
- done(error);
- });
- });
-
- it('::get', function (done) {
- socket.emit('todo::get', 'laundry', {}, function (error, data) {
- verify.get('laundry', data);
-
- done(error);
- });
- });
-
- it('::create', function (done) {
- var original = {
- name: 'creating'
- };
-
- socket.emit('todo::create', original, {}, function (error, data) {
- verify.create(original, data);
-
- done(error);
- });
- });
-
- it('::create without parameters and callback', function (done) {
- var original = {
- name: 'creating'
- };
-
- socket.emit('todo::create', original);
-
- socket.once('todo created', function(data) {
- verify.create(original, data);
-
- done();
- });
- });
-
- it('::update', function (done) {
- var original = {
- name: 'updating'
- };
-
- socket.emit('todo::update', 23, original, {}, function (error, data) {
- verify.update(23, original, data);
-
- done(error);
- });
- });
-
- it('::update many', function (done) {
- var original = {
- name: 'updating',
- many: true
- };
-
- socket.emit('todo::update', null, original, {}, function (error, data) {
- verify.update(null, original, data);
-
- done(error);
- });
- });
-
- it('::patch', function (done) {
- var original = {
- name: 'patching'
- };
-
- socket.emit('todo::patch', 25, original, {}, function (error, data) {
- verify.patch(25, original, data);
-
- done(error);
- });
- });
-
- it('::patch many', function (done) {
- var original = {
- name: 'patching',
- many: true
- };
-
- socket.emit('todo::patch', null, original, {}, function (error, data) {
- verify.patch(null, original, data);
-
- done(error);
- });
- });
-
- it('::remove', function (done) {
- socket.emit('todo::remove', 11, {}, function (error, data) {
- verify.remove(11, data);
-
- done(error);
- });
- });
-
- it('::remove many', function (done) {
- socket.emit('todo::remove', null, {}, function (error, data) {
- verify.remove(null, data);
-
- done(error);
- });
- });
- });
-
- describe('Events', function () {
- it('created', function (done) {
- var original = {
- name: 'created event'
- };
-
- socket.once('todo created', function (data) {
- verify.create(original, data);
- done();
- });
-
- socket.emit('todo::create', original, {}, function () {});
- });
-
- it('updated', function (done) {
- var original = {
- name: 'updated event'
- };
-
- socket.once('todo updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.emit('todo::update', 10, original, {}, function () {});
- });
-
- it('patched', function(done) {
- var original = {
- name: 'patched event'
- };
-
- socket.once('todo patched', function (data) {
- verify.patch(12, original, data);
- done();
- });
-
- socket.emit('todo::patch', 12, original, {}, function () {});
- });
-
- it('removed', function (done) {
- socket.once('todo removed', function (data) {
- verify.remove(333, data);
- done();
- });
-
- socket.emit('todo::remove', 333, {}, function () {});
- });
-
- it('custom events', function(done) {
- var service = app.service('todo');
- var original = {
- name: 'created event'
- };
- var old = service.create;
-
- service.create = function(data) {
- this.emit('log', { message: 'Custom log event', data: data });
- service.create = old;
- return old.apply(this, arguments);
- };
-
- socket.once('todo log', function(data) {
- assert.deepEqual(data, { message: 'Custom log event', data: original });
- done();
- });
-
- socket.emit('todo::create', original, {}, function () {});
- });
- });
-
- describe('Event filtering', function() {
- it('.created', function (done) {
- var service = app.service('todo');
- var original = { description: 'created event test' };
- var oldCreated = service.created;
-
- service.created = function(data, params, callback) {
- assert.deepEqual(params, socketParams);
- verify.create(original, data);
-
- callback(null, _.extend({ processed: true }, data));
- };
-
- socket.emit('todo::create', original, {}, function() {});
-
- socket.once('todo created', function (data) {
- service.created = oldCreated;
- // Make sure Todo got processed
- verify.create(_.extend({ processed: true }, original), data);
- done();
- });
- });
-
- it('.updated', function (done) {
- var original = {
- name: 'updated event'
- };
-
- socket.once('todo updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.emit('todo::update', 10, original, {}, function () {});
- });
-
- it('.removed', function (done) {
- var service = app.service('todo');
- var oldRemoved = service.removed;
-
- service.removed = function(data, params, callback) {
- assert.deepEqual(params, socketParams);
-
- if(data.id === 23) {
- // Only dispatch with given id
- return callback(null, data);
- }
-
- callback(null, false);
- };
-
- socket.emit('todo::remove', 1, {}, function() {});
- socket.emit('todo::remove', 23, {}, function() {});
-
- socket.on('todo removed', function (data) {
- service.removed = oldRemoved;
- assert.equal(data.id, 23);
- done();
- });
- });
- });
- });
-
- describe('Dynamic Services', function() {
- describe('CRUD', function () {
- it('::find', function (done) {
- socket.emit('tasks::find', {}, function (error, data) {
- verify.find(data);
-
- done(error);
- });
- });
-
- it('::get', function (done) {
- socket.emit('tasks::get', 'laundry', {}, function (error, data) {
- verify.get('laundry', data);
-
- done(error);
- });
- });
-
- it('::create', function (done) {
- var original = {
- name: 'creating'
- };
-
- socket.emit('tasks::create', original, {}, function (error, data) {
- verify.create(original, data);
-
- done(error);
- });
- });
-
- it('::update', function (done) {
- var original = {
- name: 'updating'
- };
-
- socket.emit('tasks::update', 23, original, {}, function (error, data) {
- verify.update(23, original, data);
-
- done(error);
- });
- });
-
- it('::patch', function (done) {
- var original = {
- name: 'patching'
- };
-
- socket.emit('tasks::patch', 25, original, {}, function (error, data) {
- verify.patch(25, original, data);
-
- done(error);
- });
- });
-
- it('::remove', function (done) {
- socket.emit('tasks::remove', 11, {}, function (error, data) {
- verify.remove(11, data);
-
- done(error);
- });
- });
- });
-
- describe('Events', function () {
- it('created', function (done) {
- var original = {
- name: 'created event'
- };
-
- socket.once('tasks created', function (data) {
- verify.create(original, data);
- done();
- });
-
- socket.emit('tasks::create', original, {}, function () {});
- });
-
- it('updated', function (done) {
- var original = {
- name: 'updated event'
- };
-
- socket.once('tasks updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.emit('tasks::update', 10, original, {}, function () {});
- });
-
- it('patched', function(done) {
- var original = {
- name: 'patched event'
- };
-
- socket.once('tasks patched', function (data) {
- verify.patch(12, original, data);
- done();
- });
-
- socket.emit('tasks::patch', 12, original, {}, function () {});
- });
-
- it('removed', function (done) {
- socket.once('tasks removed', function (data) {
- verify.remove(333, data);
- done();
- });
-
- socket.emit('tasks::remove', 333, {}, function () {});
- });
- });
-
- describe('Event Filtering', function() {
- it('.created', function (done) {
- var service = app.service('tasks');
- var original = { description: 'created event test' };
- var oldCreated = service.created;
-
- service.created = function(data, params, callback) {
- assert.ok(service === this);
- assert.deepEqual(params, socketParams);
- verify.create(original, data);
-
- callback(null, _.extend({ processed: true }, data));
- };
-
- socket.emit('tasks::create', original, {}, function() {});
-
- socket.once('tasks created', function (data) {
- service.created = oldCreated;
- // Make sure Todo got processed
- verify.create(_.extend({ processed: true }, original), data);
- done();
- });
- });
-
- it('.updated', function (done) {
- // TODO this is not testing the right thing
- // but we will get better event filtering in v2 anyway
- var original = {
- name: 'updated event'
- };
-
- socket.once('tasks updated', function (data) {
- verify.update(10, original, data);
- done();
- });
-
- socket.emit('tasks::update', 10, original, {}, function () {});
- });
-
- it('.removed', function (done) {
- var service = app.service('tasks');
- var oldRemoved = service.removed;
-
- service.removed = function(data, params, callback) {
- assert.ok(service === this);
- assert.deepEqual(params, socketParams);
-
- if(data.id === 23) {
- // Only dispatch with given id
- return callback(null, data);
- }
-
- callback(null, false);
- };
-
- socket.emit('tasks::remove', 1, {}, function() {});
- socket.emit('tasks::remove', 23, {}, function() {});
-
- socket.on('tasks removed', function (data) {
- service.removed = oldRemoved;
- assert.equal(data.id, 23);
- done();
- });
- });
- });
- });
-});

0 comments on commit f66c7d5

Please sign in to comment.
Something went wrong with that request. Please try again.