不要怂,就是干,撸起袖子干!

Commit 29ce9ba2 by Mick Hansen

Merge pull request #1001 from thanpolas/validators-error-instance

Validators yield Error instance and transport raw args
2 parents 775dd7b8 e3d05c65
......@@ -10,6 +10,9 @@ var DaoValidator = module.exports = function(model, options) {
this.options = options
}
/** @define {string} The error key for arguments as passed by custom validators */
DaoValidator.RAW_KEY_NAME = '__raw'
DaoValidator.prototype.validate = function() {
var self = this
......@@ -24,13 +27,16 @@ DaoValidator.prototype.validate = function() {
emitter.emit('success')
})
.error(function(err) {
var errors = {}
var error = new Error('Validation error')
error[DaoValidator.RAW_KEY_NAME] = []
Utils._.each(err, function (value) {
Utils._.extend(errors, value)
error[DaoValidator.RAW_KEY_NAME].push(value[DaoValidator.RAW_KEY_NAME])
delete value[DaoValidator.RAW_KEY_NAME]
Utils._.extend(error, value)
})
emitter.emit('success', errors)
emitter.emit('success', error)
})
}).run()
}
......@@ -63,7 +69,6 @@ DaoValidator.prototype.hookValidate = function() {
}
// private
var validateModel = function() {
Utils._.each(this.model.__options.validate, function(_validator, validatorType) {
var validator = prepareValidationOfAttribute.call(this, undefined, _validator, validatorType, { omitValue: true })
......@@ -72,8 +77,11 @@ var validateModel = function() {
var next = function(err) {
if (err) {
var error = {}
error[validatorType] = [err]
var error = {};
error[DaoValidator.RAW_KEY_NAME] = err
var msg = ((err instanceof Error) ? err.message : err)
error[validatorType] = [msg]
emitter.emit('error', error)
} else {
emitter.emit('success')
......@@ -155,7 +163,7 @@ var prepareValidationOfAttribute = function(value, details, validatorType, optio
try {
details.apply(this.model, callArgs)
} catch(ex) {
return next(ex.message)
return next(ex)
}
if (!isAsync) {
......
......@@ -308,7 +308,7 @@ module.exports = (function() {
.success(function (results) {
results.forEach(function (result) {
chainer.add(self.sequelize.query(
self.QueryGenerator.pgEnumDrop(null, null, result.enum_name),
self.QueryGenerator.pgEnumDrop(null, null, self.QueryGenerator.pgEscapeAndQuote(result.enum_name)),
null,
{logging: options.logging, raw: true}
))
......
......@@ -423,7 +423,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
StringIsNullOrUrl.create({ str: '' }).error(function(err) {
expect(err).to.exist
expect(err.str[0]).to.match(/Invalid URL: str/)
expect(err.str[0]).to.match(/Invalid URL/)
done()
})
......
......@@ -217,7 +217,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
failingUser.validate().done( function(err,_errors) {
expect(_errors).to.not.be.null
expect(_errors).to.deep.eql({ name : [message] })
expect(_errors).to.be.an.instanceOf(Error);
expect(_errors.name).to.eql([message])
done()
})
})
......@@ -305,7 +306,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
Model.sync({ force: true }).success(function() {
Model.create({name: 'World'}).success(function(model) {
model.updateAttributes({name: ''}).error(function(err) {
expect(err).to.deep.equal({ name: [ 'String is empty' ] })
expect(err).to.be.instanceOf(Error)
expect(err.name).to.deep.equal(['String is empty']);
done()
})
})
......@@ -326,7 +328,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
Model.sync({ force: true }).success(function() {
Model.create({name: 'World'}).success(function(model) {
Model.update({name: ''}, {id: 1}).error(function(err) {
expect(err).to.deep.equal({ name: [ 'String is empty' ] })
expect(err).to.be.instanceOf(Error)
expect(err.name).to.deep.equal(['String is empty']);
done()
})
})
......@@ -404,7 +407,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
User.sync({ force: true }).success(function() {
User.create({id: 'helloworld'}).error(function(err) {
expect(err).to.deep.equal({id: ['Invalid integer']})
expect(err).to.be.instanceOf(Error)
expect(err.id).to.deep.equal(['Invalid integer']);
done()
})
})
......@@ -424,7 +428,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
User.sync({ force: true }).success(function() {
User.create({username: 'helloworldhelloworld'}).error(function(err) {
expect(err).to.deep.equal({username: ['Username must be an integer!']})
expect(err).to.be.instanceOf(Error)
expect(err.username).to.deep.equal(['Username must be an integer!']);
done()
})
})
......@@ -450,7 +455,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
it('should emit an error when we try to enter in a string for the id key with validation arguments', function(done) {
this.User.create({id: 'helloworld'}).error(function(err) {
expect(err).to.deep.equal({id: ['ID must be an integer!']})
expect(err).to.be.instanceOf(Error)
expect(err.id).to.deep.equal(['ID must be an integer!']);
done()
})
})
......@@ -458,8 +464,9 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
it('should emit an error when we try to enter in a string for an auto increment key through .build().validate()', function(done) {
var user = this.User.build({id: 'helloworld'})
user.validate().success(function(errors) {
expect(errors).to.deep.equal({ id: [ 'ID must be an integer!' ] })
user.validate().success(function(err) {
expect(err).to.be.instanceOf(Error)
expect(err.id).to.deep.equal(['ID must be an integer!']);
done()
})
})
......@@ -467,7 +474,8 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
it('should emit an error when we try to .save()', function(done) {
var user = this.User.build({id: 'helloworld'})
user.save().error(function(err) {
expect(err).to.deep.equal({ id: [ 'ID must be an integer!' ] })
expect(err).to.be.instanceOf(Error)
expect(err.id).to.deep.equal(['ID must be an integer!']);
done()
})
})
......@@ -493,10 +501,11 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
var failingUser = User.build({ name : "3" })
failingUser.validate().success(function(errors) {
expect(errors).to.deep.equal({ name: ["name should equal '2'"] })
failingUser.validate().success(function(error) {
expect(error).to.be.instanceOf(Error);
expect(error.name).to.deep.equal(["name should equal '2'"])
var successfulUser = User.build({ name : "2" })
var successfulUser = User.build({ name : "2" })
successfulUser.validate().success(function() {
expect(arguments).to.have.length(0)
done()
......@@ -521,9 +530,10 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
User
.build({ age: -1 })
.validate()
.success(function(errors) {
expect(errors).not.to.be.null
expect(errors).to.deep.equal({ age: ['must be positive'] })
.success(function(error) {
expect(error).not.to.be.null
expect(error).to.be.instanceOf(Error);
expect(error.age).to.deep.equal(["must be positive"])
User.build({ age: null }).validate().success(function() {
User.build({ age: 1 }).validate().success(function() {
......@@ -558,9 +568,10 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
Foo
.build({ field1: null, field2: null })
.validate()
.success(function(errors) {
expect(errors).not.to.be.null
expect(errors).to.deep.equal({ 'xnor': ['xnor failed'] })
.success(function(error) {
expect(error).not.to.be.null
expect(error).to.be.instanceOf(Error)
expect(error.xnor).to.deep.equal(['xnor failed']);
Foo
.build({ field1: 33, field2: null })
......@@ -595,9 +606,10 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
Foo
.build({ field1: null, field2: null })
.validate()
.success(function(errors) {
expect(errors).not.to.be.null
expect(errors).to.deep.equal({ 'xnor': ['xnor failed'] })
.success(function(error) {
expect(error).not.to.be.null
expect(error).to.be.instanceOf(Error)
expect(error.xnor).to.deep.equal(['xnor failed']);
Foo
.build({ field1: 33, field2: null })
......@@ -665,7 +677,7 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
})
var failingBar = Bar.build({ field: 'value3' })
failingBar.validate({ skip: ['field'] }).success(function(errors) {
expect(errors).not.to.exist
done()
......
......@@ -463,7 +463,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
describe('#create', function() {
it('should return an error based on user', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ])
done()
})
})
......@@ -499,7 +500,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
describe('#create', function() {
it('should return an error based on the hook', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ])
done()
})
})
......@@ -549,7 +551,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
describe('#create', function() {
it('should return an error based on user', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ])
done()
})
})
......@@ -597,7 +600,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
describe('#create', function() {
it('should return an error based on the hook', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ])
done()
})
})
......@@ -693,7 +697,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
describe('#create', function() {
it('should return the user from the callback', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ])
done()
})
})
......@@ -714,7 +719,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
describe('#create', function() {
it('should return the error without the user within callback', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ])
done()
})
})
......@@ -828,7 +834,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) {
this.User.create({mood: 'creative'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] )
done()
})
})
......@@ -851,7 +858,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] )
done()
})
})
......@@ -931,7 +939,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
})
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] )
done()
})
})
......@@ -944,7 +953,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
})
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] )
done()
})
})
......@@ -1050,7 +1060,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) {
this.User.create({mood: 'creative'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] )
done()
})
})
......@@ -1073,7 +1084,8 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
it('#create', function(done) {
this.User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal( [ 'Value "ecstatic" for ENUM mood is out of allowed scope. Allowed values: happy, sad, neutral' ] )
done()
})
})
......@@ -1883,7 +1895,7 @@ describe(Support.getTestDialectTeaser("Hooks"), function () {
hookCalled++
next()
})
B.hasMany(A)
A.hasMany(B)
......
......@@ -123,10 +123,12 @@ if (Support.dialectIsMySQL()) {
User.sync({ force: true }).success(function() {
User.create({mood: 'happy'}).error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "happy" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "happy" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver' ])
var u = User.build({mood: 'SAD'})
u.save().error(function(err) {
expect(err).to.deep.equal({ mood: [ 'Value "SAD" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver' ] })
expect(err).to.be.instanceOf(Error);
expect(err.mood).to.deep.equal([ 'Value "SAD" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver' ])
done()
})
})
......
......@@ -633,7 +633,8 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
it("doesn't save an instance if value is not in the range of enums", function(done) {
this.Review.create({status: 'fnord'}).error(function(err) {
expect(err).to.deep.equal({ status: [ 'Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished' ] })
expect(err).to.be.instanceOf(Error);
expect(err.status).to.deep.equal([ 'Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished' ])
done()
})
})
......
......@@ -4,6 +4,7 @@ var chai = require('chai')
, Transaction = require(__dirname + '/../lib/transaction')
describe(Support.getTestDialectTeaser("Sequelize#transaction"), function () {
this.timeout(4000);
describe('success', function() {
it("gets triggered once a transaction has been successfully committed", function(done) {
this
......@@ -48,7 +49,6 @@ describe(Support.getTestDialectTeaser("Sequelize#transaction"), function () {
}).done(function() {
var dao = User.build({ name: 'foo' })
// this.QueryGenerator.insertQuery(tableName, values, dao.daoFactory.rawAttributes)
query = sequelize
.getQueryInterface()
......@@ -63,7 +63,7 @@ describe(Support.getTestDialectTeaser("Sequelize#transaction"), function () {
}).done(function(err, res) {
t.commit()
})
}, 2000)
}, 1000)
})
})
.success(function() {
......
......@@ -89,11 +89,11 @@ var Support = {
.dropAllEnums()
.success(callback)
.error(function (err) {
console.log(err)
console.log('Error in support.clearDatabase() dropAllEnums() :: ', err)
})
})
.error(function(err) {
console.log(err)
console.log('Error in support.clearDatabase() dropAllTables() :: ', err)
})
},
......
......@@ -4,6 +4,7 @@ var chai = require('chai')
, Transaction = require(__dirname + '/../lib/transaction')
describe(Support.getTestDialectTeaser("Transaction"), function () {
this.timeout(4000);
describe('constructor', function() {
it('stores options', function() {
var transaction = new Transaction(this.sequelize)
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!