diff --git a/lib/model-builder.js b/lib/model-builder.js index 63f79a8c..e18aac89 100644 --- a/lib/model-builder.js +++ b/lib/model-builder.js @@ -394,6 +394,8 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett DataType = List; } else if (DataType === Date) { DataType = DateType; + } else if (DataType === Boolean) { + DataType = BooleanType; } else if (typeof DataType === 'string') { DataType = modelBuilder.resolveType(DataType); } @@ -472,7 +474,29 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett // DataType for Date function DateType(arg) { - return new Date(arg); + var d = new Date(arg); + if (isNaN(d.getTime())) { + throw new Error('Invalid date: ' + arg); + } + return d; +} + +// Relax the Boolean coercision +function BooleanType(arg) { + if (typeof arg === 'string') { + switch (arg) { + case 'true': + case '1': + return true; + case 'false': + case '0': + return false; + } + } + if (arg == null) { + return null; + } + return Boolean(arg); } /** diff --git a/test/include.test.js b/test/include.test.js index e760508c..fa811438 100644 --- a/test/include.test.js +++ b/test/include.test.js @@ -23,7 +23,7 @@ describe('include', function () { should.not.exist(owner); } else { should.exist(owner); - owner.id.should.equal(p.ownerId); + owner.id.should.eql(p.ownerId); } }); done(); @@ -43,7 +43,7 @@ describe('include', function () { u.__cachedRelations.should.have.property('posts'); u.__cachedRelations.posts.forEach(function (p) { - p.userId.should.equal(u.id); + p.userId.should.eql(u.id); }); }); done(); @@ -68,11 +68,11 @@ describe('include', function () { should.not.exist(user); } else { should.exist(user); - user.id.should.equal(p.ownerId); + user.id.should.eql(p.ownerId); user.__cachedRelations.should.have.property('posts'); user.should.have.property('posts'); user.__cachedRelations.posts.forEach(function (pp) { - pp.userId.should.equal(user.id); + pp.userId.should.eql(user.id); }); } }); @@ -105,15 +105,15 @@ describe('include', function () { should.not.exist(user); } else { should.exist(user); - user.id.should.equal(p.ownerId); + user.id.should.eql(p.ownerId); user.__cachedRelations.should.have.property('posts'); user.__cachedRelations.posts.forEach(function (pp) { pp.should.have.property('id'); - pp.userId.should.equal(user.id); + pp.userId.should.eql(user.id); pp.should.have.property('author'); pp.__cachedRelations.should.have.property('author'); var author = pp.__cachedRelations.author; - author.id.should.equal(user.id); + author.id.should.eql(user.id); }); } }); @@ -246,10 +246,10 @@ describe('include', function () { user.__cachedRelations.should.have.property('posts'); user.__cachedRelations.should.have.property('passports'); user.__cachedRelations.posts.forEach(function (p) { - p.userId.should.equal(user.id); + p.userId.should.eql(user.id); }); user.__cachedRelations.passports.forEach(function (pp) { - pp.ownerId.should.equal(user.id); + pp.ownerId.should.eql(user.id); }); }); done(); @@ -284,11 +284,11 @@ describe('include', function () { user.__cachedRelations.should.have.property('posts'); user.__cachedRelations.should.have.property('passports'); user.__cachedRelations.posts.forEach(function(p) { - p.userId.should.equal(user.id); + p.userId.should.eql(user.id); p.title.should.be.equal('Post A'); }); user.__cachedRelations.passports.forEach(function(pp) { - pp.ownerId.should.equal(user.id); + pp.ownerId.should.eql(user.id); }); }); done(); diff --git a/test/manipulation.test.js b/test/manipulation.test.js index 8ee21977..b5af2d11 100644 --- a/test/manipulation.test.js +++ b/test/manipulation.test.js @@ -448,4 +448,76 @@ describe('manipulation', function () { // p.name.should.equal('John Resig'); // }); }); + + describe('property value coercion', function () { + it('should coerce boolean types properly', function() { + var p1 = new Person({name: 'John', married: 'false'}); + p1.married.should.equal(false); + + p1 = new Person({name: 'John', married: 'true'}); + p1.married.should.equal(true); + + p1 = new Person({name: 'John', married: '1'}); + p1.married.should.equal(true); + + p1 = new Person({name: 'John', married: '0'}); + p1.married.should.equal(false); + + p1 = new Person({name: 'John', married: true}); + p1.married.should.equal(true); + + p1 = new Person({name: 'John', married: false}); + p1.married.should.equal(false); + + p1 = new Person({name: 'John', married: 'null'}); + p1.married.should.equal(true); + + p1 = new Person({name: 'John', married: ''}); + p1.married.should.equal(false); + + p1 = new Person({name: 'John', married: 'X'}); + p1.married.should.equal(true); + + p1 = new Person({name: 'John', married: 0}); + p1.married.should.equal(false); + + p1 = new Person({name: 'John', married: 1}); + p1.married.should.equal(true); + + p1 = new Person({name: 'John', married: null}); + p1.should.have.property('married', null); + + p1 = new Person({name: 'John', married: undefined}); + p1.should.have.property('married', undefined); + + }); + + it('should coerce boolean types properly', function() { + var p1 = new Person({name: 'John', dob: '2/1/2015'}); + p1.dob.should.eql(new Date('2/1/2015')); + + p1 = new Person({name: 'John', dob: '2/1/2015'}); + p1.dob.should.eql(new Date('2/1/2015')); + + p1 = new Person({name: 'John', dob: '12'}); + p1.dob.should.eql(new Date('12')); + + p1 = new Person({name: 'John', dob: 12}); + p1.dob.should.eql(new Date(12)); + + p1 = new Person({name: 'John', dob: null}); + p1.should.have.property('dob', null); + + p1 = new Person({name: 'John', dob: undefined}); + p1.should.have.property('dob', undefined); + + try { + p1 = new Person({name: 'John', dob: 'X'}); + throw new Error('new Person() should have thrown'); + } catch (e) { + e.should.be.eql(new Error('Invalid date: X')); + } + }); + + }); });