ModelBuilder: add new setting strictEmbeddedModels

The setting controls the strict mode used for embedded property types,
for example the type of "address" property in this model definition:

    modelBuilder.define('TestEmbedded', {
      name: 'string',
      address: {
        street: 'string',
      },
    });

[back-port of #955]
This commit is contained in:
Dimitris Halatsis 2016-05-28 01:21:53 +03:00 committed by Miroslav Bajtoš
parent 0d5cff5a0a
commit 39907c6421
3 changed files with 89 additions and 3 deletions

View File

@ -44,6 +44,7 @@ function ModelBuilder() {
// create blank models pool // create blank models pool
this.models = {}; this.models = {};
this.definitions = {}; this.definitions = {};
this.settings = {};
this.mixins = new MixinProvider(this); this.mixins = new MixinProvider(this);
this.defaultModelBaseClass = DefaultModelBaseClass; this.defaultModelBaseClass = DefaultModelBaseClass;
} }
@ -703,7 +704,11 @@ ModelBuilder.prototype.resolveType = function(type) {
return this.resolveType(type.type); return this.resolveType(type.type);
} else { } else {
return this.define(this.getSchemaName(null), return this.define(this.getSchemaName(null),
type, { anonymous: true, idInjection: false }); type, {
anonymous: true,
idInjection: false,
strict: this.settings.strictEmbeddedModels || false,
});
} }
} else if ('function' === typeof type) { } else if ('function' === typeof type) {
return type; return type;

View File

@ -1902,4 +1902,83 @@ describe('ModelBuilder options.models', function() {
var M1 = builder.define('M1'); var M1 = builder.define('M1');
assert.equal(M2.M1, M1, 'M1 should be injected to M2'); assert.equal(M2.M1, M1, 'M1 should be injected to M2');
}); });
it('should use false strict mode for embedded models by default', function() {
var builder = new ModelBuilder();
var M1 = builder.define('testEmbedded', {
name: 'string',
address: {
street: 'string',
},
});
var m1 = new M1({
name: 'Jim',
address: {
street: 'washington st',
number: 5512,
},
});
assert.equal(m1.address.number, 5512, 'm1 should contain number property in address');
});
it('should use the strictEmbeddedModels setting (true) when applied on modelBuilder', function() {
var builder = new ModelBuilder();
builder.settings.strictEmbeddedModels = true;
var M1 = builder.define('testEmbedded', {
name: 'string',
address: {
street: 'string',
},
});
var m1 = new M1({
name: 'Jim',
address: {
street: 'washington st',
number: 5512,
},
});
assert.equal(m1.address.number, undefined, 'm1 should not contain number property in address');
});
it('should use strictEmbeddedModels setting (validate) when applied on modelBuilder', function() {
var builder = new ModelBuilder();
builder.settings.strictEmbeddedModels = 'validate';
var M1 = builder.define('testEmbedded', {
name: 'string',
address: {
street: 'string',
},
});
var m1 = new M1({
name: 'Jim',
address: {
street: 'washington st',
number: 5512,
},
});
assert.equal(m1.address.number, undefined, 'm1 should not contain number property in address');
assert.equal(m1.address.isValid(), false, 'm1 address should not validate with extra property');
var codes = m1.address.errors && m1.address.errors.codes || {};
assert.deepEqual(codes.number, ['unknown-property']);
});
it('should use the strictEmbeddedModels setting (throw) when applied on modelBuilder', function() {
var builder = new ModelBuilder();
builder.settings.strictEmbeddedModels = 'throw';
var M1 = builder.define('testEmbedded', {
name: 'string',
address: {
street: 'string',
},
});
assert.throws(function() {
var m1 = new M1({
name: 'Jim',
address: {
street: 'washington st',
number: 5512,
},
});
});
});
}); });

View File

@ -3837,8 +3837,10 @@ describe('relations', function() {
// db = getSchema(); // db = getSchema();
Person = db.define('Person', { name: String }); Person = db.define('Person', { name: String });
Passport = tmp.define('Passport', Passport = tmp.define('Passport',
{ id: { type: 'string', id: true, generated: true }}, {
{ name: { type: 'string', required: true }} id: { type: 'string', id: true, generated: true },
name: { type: 'string', required: true },
}
); );
}); });