diff options
Diffstat (limited to 'node_modules/mongoose/test/schema.test.js')
| -rw-r--r-- | node_modules/mongoose/test/schema.test.js | 978 |
1 files changed, 978 insertions, 0 deletions
diff --git a/node_modules/mongoose/test/schema.test.js b/node_modules/mongoose/test/schema.test.js new file mode 100644 index 0000000..93a3545 --- /dev/null +++ b/node_modules/mongoose/test/schema.test.js @@ -0,0 +1,978 @@ + +/** + * Module dependencies. + */ + +var mongoose = require('./common').mongoose + , should = require('should') + , Schema = mongoose.Schema + , Document = mongoose.Document + , SchemaType = mongoose.SchemaType + , VirtualType = mongoose.VirtualType + , ObjectId = Schema.ObjectId + , ValidatorError = SchemaType.ValidatorError + , CastError = SchemaType.CastError + , SchemaTypes = Schema.Types + , DocumentObjectId = mongoose.Types.ObjectId + , Mixed = SchemaTypes.Mixed + , MongooseNumber = mongoose.Types.Number + , MongooseArray = mongoose.Types.Array + , vm = require('vm') + +/** + * Test Document constructor. + */ + +function TestDocument () { + Document.apply(this, arguments); +}; + +/** + * Inherits from Document. + */ + +TestDocument.prototype.__proto__ = Document.prototype; + +/** + * Set a dummy schema to simulate compilation. + */ + +TestDocument.prototype.schema = new Schema({ + test : String +}); + +/** + * Test. + */ + +module.exports = { + + 'test different schema types support': function(){ + var Checkin = new Schema({ + date : Date + , location : { + lat: Number + , lng: Number + } + }); + + var Ferret = new Schema({ + name : String + , owner : ObjectId + , fur : String + , color : { type: String } + , age : Number + , checkins : [Checkin] + , friends : [ObjectId] + , likes : Array + , alive : Boolean + , extra : Mixed + }); + + Ferret.path('name').should.be.an.instanceof(SchemaTypes.String); + Ferret.path('owner').should.be.an.instanceof(SchemaTypes.ObjectId); + Ferret.path('fur').should.be.an.instanceof(SchemaTypes.String); + Ferret.path('color').should.be.an.instanceof(SchemaTypes.String); + Ferret.path('age').should.be.an.instanceof(SchemaTypes.Number); + Ferret.path('checkins').should.be.an.instanceof(SchemaTypes.DocumentArray); + Ferret.path('friends').should.be.an.instanceof(SchemaTypes.Array); + Ferret.path('likes').should.be.an.instanceof(SchemaTypes.Array); + Ferret.path('alive').should.be.an.instanceof(SchemaTypes.Boolean); + Ferret.path('extra').should.be.an.instanceof(SchemaTypes.Mixed); + + should.strictEqual(Ferret.path('unexistent'), undefined); + + Checkin.path('date').should.be.an.instanceof(SchemaTypes.Date); + }, + + 'dot notation support for accessing paths': function(){ + var Racoon = new Schema({ + name : { type: String, enum: ['Edwald', 'Tobi'] } + , age : Number + }); + + var Person = new Schema({ + name : String + , raccoons : [Racoon] + , location : { + city : String + , state : String + } + }); + + Person.path('name').should.be.an.instanceof(SchemaTypes.String); + Person.path('raccoons').should.be.an.instanceof(SchemaTypes.DocumentArray); + Person.path('location.city').should.be.an.instanceof(SchemaTypes.String); + Person.path('location.state').should.be.an.instanceof(SchemaTypes.String); + + should.strictEqual(Person.path('location.unexistent'), undefined); + }, + + 'nested paths more than 2 levels deep': function () { + var Nested = new Schema({ + first: { + second: { + third: String + } + } + }); + Nested.path('first.second.third').should.be.an.instanceof(SchemaTypes.String); + }, + + 'test default definition': function(){ + var Test = new Schema({ + simple : { type: String, default: 'a' } + , array : { type: Array, default: [1,2,3,4,5] } + , arrayX : { type: Array, default: 9 } + , arrayFn : { type: Array, default: function () { return [8] } } + , callback : { type: Number, default: function(){ + this.a.should.eql('b'); + return '3'; + }} + }); + + Test.path('simple').defaultValue.should.eql('a'); + Test.path('callback').defaultValue.should.be.a('function'); + + Test.path('simple').getDefault().should.eql('a'); + (+Test.path('callback').getDefault({ a: 'b' })).should.eql(3); + Test.path('array').defaultValue.should.be.a('function'); + Test.path('array').getDefault(new TestDocument)[3].should.eql(4); + Test.path('arrayX').getDefault(new TestDocument)[0].should.eql(9); + Test.path('arrayFn').defaultValue.should.be.a('function'); + Test.path('arrayFn').getDefault(new TestDocument).should.be.an.instanceof(MongooseArray); + }, + + 'test Mixed defaults can be empty arrays': function () { + var Test = new Schema({ + mixed1 : { type: Mixed, default: [] } + , mixed2 : { type: Mixed, default: Array } + }); + + Test.path('mixed1').getDefault().should.be.an.instanceof(Array); + Test.path('mixed1').getDefault().length.should.be.eql(0); + Test.path('mixed2').getDefault().should.be.an.instanceof(Array); + Test.path('mixed2').getDefault().length.should.be.eql(0); + }, + + 'test string required validation': function(){ + var Test = new Schema({ + simple: String + }); + + Test.path('simple').required(true); + Test.path('simple').validators.should.have.length(1); + + Test.path('simple').doValidate(null, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Test.path('simple').doValidate(undefined, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Test.path('simple').doValidate('', function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Test.path('simple').doValidate('woot', function(err){ + should.strictEqual(err, null); + }); + }, + + 'test string enum validation': function(){ + var Test = new Schema({ + complex: { type: String, enum: ['a', 'b', undefined, 'c', null] } + }); + + Test.path('complex').should.be.an.instanceof(SchemaTypes.String); + Test.path('complex').enumValues.should.eql(['a', 'b', 'c', null]); + Test.path('complex').validators.should.have.length(1); + + Test.path('complex').enum('d', 'e'); + + Test.path('complex').enumValues.should.eql(['a', 'b', 'c', null, 'd', 'e']); + + Test.path('complex').doValidate('x', function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Test.path('complex').doValidate(undefined, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Test.path('complex').doValidate(null, function(err){ + should.strictEqual(null, err); + }); + + Test.path('complex').doValidate('da', function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + }, + + 'test string regular expression validation': function(){ + var Test = new Schema({ + simple: { type: String, match: /[a-z]/ } + }); + + Test.path('simple').validators.should.have.length(1); + + Test.path('simple').doValidate('az', function(err){ + should.strictEqual(err, null); + }); + + Test.path('simple').match(/[0-9]/); + Test.path('simple').validators.should.have.length(2); + + Test.path('simple').doValidate('12', function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Test.path('simple').doValidate('a12', function(err){ + should.strictEqual(err, null); + }); + }, + + 'test string casting': function(){ + var Tobi = new Schema({ + nickname: String + }); + + function Test(){}; + Test.prototype.toString = function(){ + return 'woot'; + }; + + // test Number -> String cast + Tobi.path('nickname').cast(0).should.be.a('string'); + Tobi.path('nickname').cast(0).should.eql('0'); + + // test any object that implements toString + Tobi.path('nickname').cast(new Test()).should.be.a('string'); + Tobi.path('nickname').cast(new Test()).should.eql('woot'); + }, + + 'test number minimums and maximums validation': function(){ + var Tobi = new Schema({ + friends: { type: Number, max: 15, min: 5 } + }); + + Tobi.path('friends').validators.should.have.length(2); + + Tobi.path('friends').doValidate(10, function(err){ + should.strictEqual(err, null); + }); + + Tobi.path('friends').doValidate(100, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Tobi.path('friends').doValidate(1, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + // null is allowed + Tobi.path('friends').doValidate(null, function(err){ + should.strictEqual(err, null); + }); + }, + + 'test number required validation': function(){ + var Edwald = new Schema({ + friends: { type: Number, required: true } + }); + + Edwald.path('friends').doValidate(null, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Edwald.path('friends').doValidate(undefined, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Edwald.path('friends').doValidate(0, function(err){ + should.strictEqual(err, null); + }); + }, + + 'test number casting': function(){ + var Tobi = new Schema({ + age: Number + }); + + // test String -> Number cast + Tobi.path('age').cast('0').should.be.an.instanceof(MongooseNumber); + (+Tobi.path('age').cast('0')).should.eql(0); + + Tobi.path('age').cast(0).should.be.an.instanceof(MongooseNumber); + (+Tobi.path('age').cast(0)).should.eql(0); + }, + + 'test date required validation': function(){ + var Loki = new Schema({ + birth_date: { type: Date, required: true } + }); + + Loki.path('birth_date').doValidate(null, function (err) { + err.should.be.an.instanceof(ValidatorError); + }); + + Loki.path('birth_date').doValidate(undefined, function (err) { + err.should.be.an.instanceof(ValidatorError); + }); + + Loki.path('birth_date').doValidate(new Date(), function (err) { + should.strictEqual(err, null); + }); + }, + + 'test date casting': function(){ + var Loki = new Schema({ + birth_date: { type: Date } + }); + + Loki.path('birth_date').cast(1294525628301).should.be.an.instanceof(Date); + Loki.path('birth_date').cast('8/24/2000').should.be.an.instanceof(Date); + Loki.path('birth_date').cast(new Date).should.be.an.instanceof(Date); + }, + + 'test object id required validator': function(){ + var Loki = new Schema({ + owner: { type: ObjectId, required: true } + }); + + Loki.path('owner').doValidate(new DocumentObjectId(), function(err){ + should.strictEqual(err, null); + }); + + Loki.path('owner').doValidate(null, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Loki.path('owner').doValidate(undefined, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + }, + + 'test object id casting': function(){ + var Loki = new Schema({ + owner: { type: ObjectId } + }); + + var doc = new TestDocument() + , id = doc._id.toString(); + + Loki.path('owner').cast('4c54f3453e688c000000001a') + .should.be.an.instanceof(DocumentObjectId); + + Loki.path('owner').cast(new DocumentObjectId()) + .should.be.an.instanceof(DocumentObjectId); + + Loki.path('owner').cast(doc) + .should.be.an.instanceof(DocumentObjectId); + + Loki.path('owner').cast(doc).toString().should.eql(id); + }, + + 'test array required validation': function(){ + var Loki = new Schema({ + likes: { type: Array, required: true } + }); + + Loki.path('likes').doValidate(null, function (err) { + err.should.be.an.instanceof(ValidatorError); + }); + + Loki.path('likes').doValidate(undefined, function (err) { + err.should.be.an.instanceof(ValidatorError); + }); + + Loki.path('likes').doValidate([], function (err) { + err.should.be.an.instanceof(ValidatorError); + }); + }, + + 'test array casting': function(){ + var Loki = new Schema({ + oids : [ObjectId] + , dates : [Date] + , numbers : [Number] + , strings : [String] + , buffers : [Buffer] + , nocast : [] + , mixed : [Mixed] + }); + + var oids = Loki.path('oids').cast(['4c54f3453e688c000000001a', new DocumentObjectId]); + + oids[0].should.be.an.instanceof(DocumentObjectId); + oids[1].should.be.an.instanceof(DocumentObjectId); + + var dates = Loki.path('dates').cast(['8/24/2010', 1294541504958]); + + dates[0].should.be.an.instanceof(Date); + dates[1].should.be.an.instanceof(Date); + + var numbers = Loki.path('numbers').cast([152, '31']); + + numbers[0].should.be.a('number'); + numbers[1].should.be.a('number'); + + var strings = Loki.path('strings').cast(['test', 123]); + + strings[0].should.be.a('string'); + strings[0].should.eql('test'); + + strings[1].should.be.a('string'); + strings[1].should.eql('123'); + + var buffers = Loki.path('buffers').cast(['\0\0\0', new Buffer("abc")]); + + buffers[0].should.be.an.instanceof(Buffer); + buffers[1].should.be.an.instanceof(Buffer); + + var nocasts = Loki.path('nocast').cast(['test', 123]); + + nocasts[0].should.be.a('string'); + nocasts[0].should.eql('test'); + + nocasts[1].should.be.a('number'); + nocasts[1].should.eql(123); + + var mixed = Loki.path('mixed').cast(['test', 123, '123', {}, new Date, new DocumentObjectId]); + + mixed[0].should.be.a('string'); + mixed[1].should.be.a('number'); + mixed[2].should.be.a('string'); + mixed[3].should.be.a('object'); + mixed[4].should.be.an.instanceof(Date); + mixed[5].should.be.an.instanceof(DocumentObjectId); + }, + + 'test boolean required validator': function(){ + var Animal = new Schema({ + isFerret: { type: Boolean, required: true } + }); + + Animal.path('isFerret').doValidate(null, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Animal.path('isFerret').doValidate(undefined, function(err){ + err.should.be.an.instanceof(ValidatorError); + }); + + Animal.path('isFerret').doValidate(true, function(err){ + should.strictEqual(err, null); + }); + + Animal.path('isFerret').doValidate(false, function(err){ + should.strictEqual(err, null); + }); + }, + + 'test boolean casting': function(){ + var Animal = new Schema({ + isFerret: { type: Boolean, required: true } + }); + + should.strictEqual(Animal.path('isFerret').cast(null), null); + Animal.path('isFerret').cast(undefined).should.be.false; + Animal.path('isFerret').cast(false).should.be.false; + Animal.path('isFerret').cast(0).should.be.false; + Animal.path('isFerret').cast('0').should.be.false; + Animal.path('isFerret').cast({}).should.be.true; + Animal.path('isFerret').cast(true).should.be.true; + Animal.path('isFerret').cast(1).should.be.true; + Animal.path('isFerret').cast('1').should.be.true; + }, + + 'test async multiple validators': function(beforeExit){ + var executed = 0; + + function validator (value, fn) { + setTimeout(function(){ + executed++; + fn(value === true); + }, 50); + }; + + var Animal = new Schema({ + ferret: { + type: Boolean, + validate: [ + { + 'validator': validator, + 'msg': 'validator1' + }, + { + 'validator': validator, + 'msg': 'validator2' + }, + ], + } + }); + + Animal.path('ferret').doValidate(true, function(err){ + should.strictEqual(err, null); + }); + + beforeExit(function(){ + executed.should.eql(2); + }); + }, + + 'test async validators': function(beforeExit){ + var executed = 0; + + function validator (value, fn) { + setTimeout(function(){ + executed++; + fn(value === true); + }, 50); + }; + + var Animal = new Schema({ + ferret: { type: Boolean, validate: validator } + }); + + Animal.path('ferret').doValidate(true, function(err){ + should.strictEqual(err, null); + }); + + Animal.path('ferret').doValidate(false, function(err){ + err.should.be.an.instanceof(Error); + }); + + beforeExit(function(){ + executed.should.eql(2); + }); + }, + + 'test async validators scope': function(beforeExit){ + var executed = false; + + function validator (value, fn) { + this.a.should.eql('b'); + + setTimeout(function(){ + executed = true; + fn(true); + }, 50); + }; + + var Animal = new Schema({ + ferret: { type: Boolean, validate: validator } + }); + + Animal.path('ferret').doValidate(true, function(err){ + should.strictEqual(err, null); + }, { a: 'b' }); + + beforeExit(function(){ + executed.should.be.true; + }); + }, + + 'test declaring new methods': function(){ + var a = new Schema(); + a.method('test', function(){}); + a.method({ + a: function(){} + , b: function(){} + }); + + Object.keys(a.methods).should.have.length(3); + }, + + 'test declaring new statics': function(){ + var a = new Schema(); + a.static('test', function(){}); + a.static({ + a: function(){} + , b: function(){} + , c: function(){} + }); + + Object.keys(a.statics).should.have.length(4); + }, + + 'test setter(s)': function(){ + function lowercase (v) { + return v.toLowerCase(); + }; + + var Tobi = new Schema({ + name: { type: String, set: lowercase } + }); + + Tobi.path('name').applySetters('WOOT').should.eql('woot'); + Tobi.path('name').setters.should.have.length(1); + + Tobi.path('name').set(function(v){ + return v + 'WOOT'; + }); + + Tobi.path('name').applySetters('WOOT').should.eql('wootwoot'); + Tobi.path('name').setters.should.have.length(2); + }, + + 'test setters scope': function(){ + function lowercase (v, self) { + this.a.should.eql('b'); + self.path.should.eql('name'); + return v.toLowerCase(); + }; + + var Tobi = new Schema({ + name: { type: String, set: lowercase } + }); + + Tobi.path('name').applySetters('WHAT', { a: 'b' }).should.eql('what'); + }, + + 'test string built-in setter `lowercase`': function () { + var Tobi = new Schema({ + name: { type: String, lowercase: true } + }); + + Tobi.path('name').applySetters('WHAT').should.eql('what'); + }, + + 'test string built-in setter `uppercase`': function () { + var Tobi = new Schema({ + name: { type: String, uppercase: true } + }); + + Tobi.path('name').applySetters('what').should.eql('WHAT'); + }, + + 'test string built-in setter `trim`': function () { + var Tobi = new Schema({ + name: { type: String, uppercase: true, trim: true } + }); + + Tobi.path('name').applySetters(' what ').should.eql('WHAT'); + }, + + 'test getter(s)': function(){ + function woot (v) { + return v + ' woot'; + }; + + var Tobi = new Schema({ + name: { type: String, get: woot } + }); + + Tobi.path('name').getters.should.have.length(1); + Tobi.path('name').applyGetters('test').should.eql('test woot'); + }, + + 'test getters scope': function(){ + function woot (v, self) { + this.a.should.eql('b'); + self.path.should.eql('name'); + return v.toLowerCase(); + }; + + var Tobi = new Schema({ + name: { type: String, get: woot } + }); + + Tobi.path('name').applyGetters('YEP', { a: 'b' }).should.eql('yep'); + }, + + 'test setters casting': function(){ + function last (v) { + v.should.be.a('string'); + v.should.eql('0'); + return 'last'; + }; + + function first (v) { + return 0; + }; + + var Tobi = new Schema({ + name: { type: String, set: last } + }); + + Tobi.path('name').set(first); + Tobi.path('name').applySetters('woot').should.eql('last'); + }, + + 'test getters casting': function(){ + function last (v) { + v.should.be.a('string'); + v.should.eql('0'); + return 'last'; + }; + + function first (v) { + return 0; + }; + + var Tobi = new Schema({ + name: { type: String, get: last } + }); + + Tobi.path('name').get(first); + Tobi.path('name').applyGetters('woot').should.eql('last'); + }, + + 'test hooks registration': function(){ + var Tobi = new Schema(); + + Tobi.pre('save', function(){}); + Tobi.callQueue.should.have.length(1); + + Tobi.post('save', function(){}); + Tobi.callQueue.should.have.length(2); + + Tobi.pre('save', function(){}); + Tobi.callQueue.should.have.length(3); + }, + + 'test applying setters when none have been defined': function(){ + var Tobi = new Schema({ + name: String + }); + + Tobi.path('name').applySetters('woot').should.eql('woot'); + }, + + 'test applying getters when none have been defined': function(){ + var Tobi = new Schema({ + name: String + }); + + Tobi.path('name').applyGetters('woot').should.eql('woot'); + }, + + 'test defining an index': function(){ + var Tobi = new Schema({ + name: { type: String, index: true } + }); + + Tobi.path('name')._index.should.be.true; + Tobi.path('name').index({ unique: true }); + Tobi.path('name')._index.should.eql({ unique: true }); + Tobi.path('name').unique(false); + Tobi.path('name')._index.should.eql({ unique: false}); + + var T1 = new Schema({ + name: { type: String, sparse: true } + }); + T1.path('name')._index.should.eql({ sparse: true }); + + var T2 = new Schema({ + name: { type: String, unique: true } + }); + T2.path('name')._index.should.eql({ unique: true }); + + var T3 = new Schema({ + name: { type: String, sparse: true, unique: true } + }); + T3.path('name')._index.should.eql({ sparse: true, unique: true }); + + var T4 = new Schema({ + name: { type: String, unique: true, sparse: true } + }); + var i = T4.path('name')._index; + i.unique.should.be.true; + i.sparse.should.be.true; + + var T5 = new Schema({ + name: { type: String, index: { sparse: true, unique: true } } + }); + var i = T5.path('name')._index; + i.unique.should.be.true; + i.sparse.should.be.true; + }, + + 'test defining compound indexes': function(){ + var Tobi = new Schema({ + name: { type: String, index: true } + , last: { type: Number, sparse: true } + }); + + Tobi.index({ firstname: 1, last: 1 }, { unique: true }); + + Tobi.indexes.should.eql([ + [{ name: 1 }, {}] + , [{ last: 1 }, { sparse: true }] + , [{ firstname: 1, last: 1}, {unique: true}] + ]); + }, + + 'test plugins': function (beforeExit) { + var Tobi = new Schema() + , called = false; + + Tobi.plugin(function(schema){ + schema.should.equal(Tobi); + called = true; + }); + + beforeExit(function () { + called.should.be.true; + }); + }, + + 'test that default options are set': function () { + var Tobi = new Schema(); + + Tobi.options.should.be.a('object'); + Tobi.options.safe.should.be.true; + }, + + 'test setting options': function () { + var Tobi = new Schema({}, { collection: 'users' }); + + Tobi.set('a', 'b'); + Tobi.set('safe', false); + Tobi.options.collection.should.eql('users'); + + Tobi.options.a.should.eql('b'); + Tobi.options.safe.should.be.false; + }, + + 'test declaring virtual attributes': function () { + var Contact = new Schema({ + firstName: String + , lastName: String + }); + Contact.virtual('fullName') + .get( function () { + return this.get('firstName') + ' ' + this.get('lastName'); + }).set(function (fullName) { + var split = fullName.split(' '); + this.set('firstName', split[0]); + this.set('lastName', split[1]); + }); + + Contact.virtualpath('fullName').should.be.an.instanceof(VirtualType); + }, + + 'test GH-298 - The default creation of a virtual `id` should be muted when someone defines their own `id` attribute': function () { + new Schema({ id: String }); + }, + + 'allow disabling the auto .id virtual': function () { + var schema = new Schema({ name: String }, { noVirtualId: true }); + should.strictEqual(undefined, schema.virtuals.id); + }, + + 'selected option': function () { + var s = new Schema({ thought: { type: String, select: false }}); + s.path('thought').selected.should.be.false; + + var a = new Schema({ thought: { type: String, select: true }}); + a.path('thought').selected.should.be.true; + }, + + 'schema creation works with objects from other contexts': function () { + var str = 'code = {' + + ' name: String' + + ', arr1: Array ' + + ', arr2: { type: [] }' + + ', date: Date ' + + ', num: { type: Number }' + + ', bool: Boolean' + + ', nest: { sub: { type: {}, required: true }}' + + '}'; + + var script = vm.createScript(str, 'testSchema.vm'); + var sandbox = { code: null }; + script.runInNewContext(sandbox); + + var Ferret = new Schema(sandbox.code); + Ferret.path('nest.sub').should.be.an.instanceof(SchemaTypes.Mixed); + Ferret.path('name').should.be.an.instanceof(SchemaTypes.String); + Ferret.path('arr1').should.be.an.instanceof(SchemaTypes.Array); + Ferret.path('arr2').should.be.an.instanceof(SchemaTypes.Array); + Ferret.path('date').should.be.an.instanceof(SchemaTypes.Date); + Ferret.path('num').should.be.an.instanceof(SchemaTypes.Number); + Ferret.path('bool').should.be.an.instanceof(SchemaTypes.Boolean); + }, + + 'schema string casts undefined to "undefined"': function () { + var db= require('./common')(); + var schema = new Schema({ arr: [String] }); + var M = db.model('castingStringArrayWithUndefined', schema); + M.find({ arr: { $in: [undefined] }}, function (err) { + db.close(); + should.equal(err && err.message, 'Cast to string failed for value "undefined"'); + }) + }, + + 'array of object literal missing a `type` is interpreted as Mixed': function () { + var s = new Schema({ + arr: [ + { something: { type: String } } + ] + }); + }, + + 'helpful schema debugging msg': function () { + var err; + try { + new Schema({ name: { first: null } }) + } catch (e) { + err = e; + } + err.message.should.equal('Invalid value for schema path `name.first`') + try { + new Schema({ age: undefined }) + } catch (e) { + err = e; + } + err.message.should.equal('Invalid value for schema path `age`') + }, + + 'add() does not polute existing paths': function () { + var o = { name: String } + var s = new Schema(o); + s.add({ age: Number }, 'name.'); + ;('age' in o.name).should.be.false; + }, + + // gh-700 + 'nested schemas should throw': function () { + var a = new Schema({ title: String }) + , err + + try { + new Schema({ blah: Boolean, a: a }); + } catch (err_) { + err = err_; + } + + should.exist(err); + ;/Did you try nesting Schemas/.test(err.message).should.be.true; + }, + + 'non-function etters throw': function () { + var schema = new Schema({ fun: String }); + var g, s; + + try { + schema.path('fun').get(true); + } catch (err_) { + g = err_; + } + + should.exist(g); + g.message.should.equal('A getter must be a function.'); + + try { + schema.path('fun').set(4); + } catch (err_) { + s = err_; + } + + should.exist(s); + s.message.should.equal('A setter must be a function.'); + } + +}; |
