Merge pull request #2703 from strongloop/fix_remoting

Fix remote method inheritance
This commit is contained in:
Candy 2016-09-13 13:56:43 -04:00 committed by GitHub
commit 6752dd3af3
2 changed files with 142 additions and 1 deletions

View File

@ -121,7 +121,7 @@ Registry.prototype.createModel = function(name, properties, options) {
var model = BaseModel.extend(name, properties, options); var model = BaseModel.extend(name, properties, options);
model.registry = this; model.registry = this;
this._defineRemoteMethods(model, options.methods); this._defineRemoteMethods(model, model.settings.methods);
return model; return model;
}; };
@ -244,6 +244,15 @@ Registry.prototype.configureModel = function(ModelCtor, config) {
modelName); modelName);
} }
var newMethodNames = config.methods && Object.keys(config.methods);
var hasNewMethods = newMethodNames && newMethodNames.length;
var hasDescendants = this.getModelByType(ModelCtor) !== ModelCtor;
if (hasNewMethods && hasDescendants) {
g.warn(
'Child models of `%s` will not inherit newly defined remote methods %s.',
modelName, newMethodNames);
}
// Remote methods // Remote methods
this._defineRemoteMethods(ModelCtor, config.methods); this._defineRemoteMethods(ModelCtor, config.methods);
}; };

View File

@ -7,6 +7,9 @@ var it = require('./util/it');
var describe = require('./util/describe'); var describe = require('./util/describe');
var Domain = require('domain'); var Domain = require('domain');
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var loopback = require('../');
var expect = require('chai').expect;
var assert = require('assert');
describe('loopback', function() { describe('loopback', function() {
var nameCounter = 0; var nameCounter = 0;
@ -608,4 +611,133 @@ describe('loopback', function() {
expect(methodNames).to.include('prototype.instanceMethod'); expect(methodNames).to.include('prototype.instanceMethod');
}); });
}); });
describe('Remote method inheritance', function() {
var app;
beforeEach(setupLoopback);
it('inherits remote methods defined via createModel', function() {
var Base = app.registry.createModel('Base', {}, {
methods: {
greet: {
http: { path: '/greet' },
},
},
});
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
methods: {
hello: {
http: { path: '/hello' },
},
},
});
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
expect(methodNames).to.include('greet');
expect(methodNames).to.include('hello');
});
it('same remote method with different metadata should override parent', function() {
var Base = app.registry.createModel('Base', {}, {
methods: {
greet: {
http: { path: '/greet' },
},
},
});
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
methods: {
greet: {
http: { path: '/hello' },
},
},
});
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
var baseMethod = Base.sharedClass.findMethodByName('greet');
var customMethod = MyCustomModel.sharedClass.findMethodByName('greet');
// Base Method
expect(baseMethod.http).to.eql({ path: '/greet' });
expect(baseMethod.http.path).to.equal('/greet');
expect(baseMethod.http.path).to.not.equal('/hello');
// Custom Method
expect(methodNames).to.include('greet');
expect(customMethod.http).to.eql({ path: '/hello' });
expect(customMethod.http.path).to.equal('/hello');
expect(customMethod.http.path).to.not.equal('/greet');
});
it('does not inherit remote methods defined via configureModel', function() {
var Base = app.registry.createModel('Base');
app.registry.configureModel(Base, {
dataSource: null,
methods: {
greet: {
http: { path: '/greet' },
},
},
});
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
methods: {
hello: {
http: { path: '/hello' },
},
},
});
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
expect(methodNames).to.not.include('greet');
expect(methodNames).to.include('hello');
});
it('does not inherit remote methods defined via configureModel after child model ' +
'was created', function() {
var Base = app.registry.createModel('Base');
var MyCustomModel = app.registry.createModel('MyCustomModel', {}, {
base: 'Base',
});
app.registry.configureModel(Base, {
dataSource: null,
methods: {
greet: {
http: { path: '/greet' },
},
},
});
app.registry.configureModel(MyCustomModel, {
dataSource: null,
methods: {
hello: {
http: { path: '/hello' },
},
},
});
var baseMethodNames = getAllMethodNamesWithoutClassName(Base);
var methodNames = getAllMethodNamesWithoutClassName(MyCustomModel);
expect(baseMethodNames).to.include('greet');
expect(methodNames).to.not.include('greet');
expect(methodNames).to.include('hello');
});
function setupLoopback() {
app = loopback({ localRegistry: true });
}
function getAllMethodNamesWithoutClassName(Model) {
return Model.sharedClass.methods().map(function(m) {
return m.stringName.replace(/^[^.]+\./, ''); // drop the class name
});
}
});
}); });