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/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')); + } + }); + + }); });