Merge pull request #49 from strongloop/feature/merge-settings

Merge settings for base and sub models
This commit is contained in:
Raymond Feng 2013-12-06 16:20:25 -08:00
commit 99230efe80
3 changed files with 146 additions and 0 deletions

View File

@ -9,6 +9,7 @@ var assert = require('assert');
var DefaultModelBaseClass = require('./model.js');
var List = require('./list.js');
var ModelDefinition = require('./model-definition.js');
var mergeSettings = require('./utils').mergeSettings;
// Set up types
require('./types')(ModelBuilder);
@ -283,11 +284,15 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
});
// Merge the settings
subclassSettings = mergeSettings(settings, subclassSettings);
/*
Object.keys(settings).forEach(function (key) {
if(subclassSettings[key] === undefined) {
subclassSettings[key] = settings[key];
}
});
*/
// Define the subclass
var subClass = modelBuilder.define(className, subclassProperties, subclassSettings, ModelClass);

View File

@ -3,6 +3,7 @@ exports.fieldsToArray = fieldsToArray;
exports.selectFields = selectFields;
exports.removeUndefined = removeUndefined;
exports.parseSettings = parseSettings;
exports.mergeSettings = mergeSettings;
var traverse = require('traverse');
@ -127,3 +128,53 @@ function parseSettings(urlStr) {
}
return settings;
}
/**
* Merge model settings
*
* Folked from https://github.com/nrf110/deepmerge/blob/master/index.js
*
* The original function tries to merge array items if they are objects
*
* @param {Object} target The target settings object
* @param {Object} src The source settings object
* @returns {Object} The merged settings object
*/
function mergeSettings(target, src) {
var array = Array.isArray(src);
var dst = array && [] || {};
if (array) {
target = target || [];
dst = dst.concat(target);
src.forEach(function (e, i) {
if (typeof target[i] === 'undefined') {
dst[i] = e;
} else {
if (target.indexOf(e) === -1) {
dst.push(e);
}
}
});
} else {
if (target && typeof target === 'object') {
Object.keys(target).forEach(function (key) {
dst[key] = target[key];
});
}
Object.keys(src).forEach(function (key) {
if (typeof src[key] !== 'object' || !src[key]) {
dst[key] = src[key];
}
else {
if (!target[key]) {
dst[key] = src[key]
} else {
dst[key] = mergeSettings(target[key], src[key])
}
}
});
}
return dst;
}

View File

@ -649,6 +649,96 @@ describe('Load models from json', function () {
done(null, customer);
});
it('should be able to extend models with merged settings', function (done) {
var modelBuilder = new ModelBuilder();
var User = modelBuilder.define('User', {
name: String
}, {
defaultPermission: 'ALLOW',
acls: [
{
principalType: 'ROLE',
principalId: '$everyone',
permission: 'ALLOW'
}
],
relations: {
posts: {
type: 'hasMany',
model:'Post'
}
}
});
var Customer = User.extend('Customer',
{customerId: {type: String, id: true}},
{
defaultPermission: 'DENY',
acls: [
{
principalType: 'ROLE',
principalId: '$unauthenticated',
permission: 'DENY'
}
],
relations: {
orders: {
type: 'hasMany',
model:'Order'
}
}
}
);
assert.deepEqual(User.settings, {
defaultPermission: 'ALLOW',
acls: [
{
principalType: 'ROLE',
principalId: '$everyone',
permission: 'ALLOW'
}
],
relations: {
posts: {
type: 'hasMany',
model:'Post'
}
},
strict: false
});
assert.deepEqual(Customer.settings, {
defaultPermission: 'DENY',
acls: [
{
principalType: 'ROLE',
principalId: '$everyone',
permission: 'ALLOW'
},
{
principalType: 'ROLE',
principalId: '$unauthenticated',
permission: 'DENY'
}
],
relations: {
posts: {
type: 'hasMany',
model:'Post'
},
orders: {
type: 'hasMany',
model:'Order'
}
},
strict: false
});
done();
});
});
describe('DataSource constructor', function(){