Rewrite custom validation
This commit is contained in:
parent
e55b29e479
commit
9dcd976546
|
@ -10,17 +10,7 @@ Validatable.validatesNumericalityOf = getConfigurator('numericality');
|
||||||
Validatable.validatesInclusionOf = getConfigurator('inclusion');
|
Validatable.validatesInclusionOf = getConfigurator('inclusion');
|
||||||
Validatable.validatesExclusionOf = getConfigurator('exclusion');
|
Validatable.validatesExclusionOf = getConfigurator('exclusion');
|
||||||
Validatable.validatesFormatOf = getConfigurator('format');
|
Validatable.validatesFormatOf = getConfigurator('format');
|
||||||
Validatable.validate = function () {
|
Validatable.validate = getConfigurator('custom');
|
||||||
args = [].slice.call(arguments);
|
|
||||||
var valFn = function () {}; // noop
|
|
||||||
if (typeof args[args.length - 1] === 'function'){
|
|
||||||
valFn = args.pop();
|
|
||||||
}
|
|
||||||
wrapperFn = function customValidator(attr, conf, err) {
|
|
||||||
return valFn.call(this, err);
|
|
||||||
};
|
|
||||||
configure(this, wrapperFn, args)
|
|
||||||
};
|
|
||||||
|
|
||||||
// implementation of validators
|
// implementation of validators
|
||||||
var validators = {
|
var validators = {
|
||||||
|
@ -77,13 +67,16 @@ var validators = {
|
||||||
} else {
|
} else {
|
||||||
err();
|
err();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
custom: function (attr, conf, err) {
|
||||||
|
conf.customValidator.call(this, err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function getConfigurator(name) {
|
function getConfigurator(name, opts) {
|
||||||
return function () {
|
return function () {
|
||||||
configure(this, name, arguments);
|
configure(this, name, arguments, opts);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +117,9 @@ function cleanErrors(inst) {
|
||||||
function validationFailed(inst, v) {
|
function validationFailed(inst, v) {
|
||||||
var attr = v[0];
|
var attr = v[0];
|
||||||
var conf = v[1];
|
var conf = v[1];
|
||||||
|
var opts = v[2] || {};
|
||||||
|
|
||||||
|
if (typeof attr !== 'string') return false;
|
||||||
|
|
||||||
// here we should check skip validation conditions (if, unless)
|
// here we should check skip validation conditions (if, unless)
|
||||||
// that can be specified in conf
|
// that can be specified in conf
|
||||||
|
@ -131,8 +127,11 @@ function validationFailed(inst, v) {
|
||||||
if (skipValidation(inst, conf, 'unless')) return false;
|
if (skipValidation(inst, conf, 'unless')) return false;
|
||||||
|
|
||||||
var fail = false;
|
var fail = false;
|
||||||
var validator = typeof conf.validation === "function" ? conf.validation : validators[conf.validation];
|
var validator = validators[conf.validation];
|
||||||
validator.call(inst, attr, conf, function onerror(kind) {
|
var validatorArguments = [];
|
||||||
|
validatorArguments.push(attr);
|
||||||
|
validatorArguments.push(conf);
|
||||||
|
validatorArguments.push(function onerror(kind) {
|
||||||
var message;
|
var message;
|
||||||
if (conf.message) {
|
if (conf.message) {
|
||||||
message = conf.message;
|
message = conf.message;
|
||||||
|
@ -154,6 +153,7 @@ function validationFailed(inst, v) {
|
||||||
inst.errors.add(attr, message);
|
inst.errors.add(attr, message);
|
||||||
fail = true;
|
fail = true;
|
||||||
});
|
});
|
||||||
|
validator.apply(inst, validatorArguments);
|
||||||
return fail;
|
return fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ function blank(v) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure(cls, validation, args) {
|
function configure(cls, validation, args, opts) {
|
||||||
if (!cls._validations) {
|
if (!cls._validations) {
|
||||||
Object.defineProperty(cls, '_validations', {
|
Object.defineProperty(cls, '_validations', {
|
||||||
writable: true,
|
writable: true,
|
||||||
|
@ -237,9 +237,12 @@ function configure(cls, validation, args) {
|
||||||
} else {
|
} else {
|
||||||
conf = {};
|
conf = {};
|
||||||
}
|
}
|
||||||
|
if (validation === 'custom' && typeof args[args.length - 1] === 'function') {
|
||||||
|
conf.customValidator = args.pop();
|
||||||
|
}
|
||||||
conf.validation = validation;
|
conf.validation = validation;
|
||||||
args.forEach(function (attr) {
|
args.forEach(function (attr) {
|
||||||
cls._validations.push([attr, conf]);
|
cls._validations.push([attr, conf, opts]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,3 +256,4 @@ Errors.prototype.add = function (field, message) {
|
||||||
this[field].push(message);
|
this[field].push(message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -77,3 +77,4 @@ it "should trigger after destroy", (test)->
|
||||||
test.done()
|
test.done()
|
||||||
User.create {}, (err, user)->
|
User.create {}, (err, user)->
|
||||||
user.destroy()
|
user.destroy()
|
||||||
|
|
||||||
|
|
|
@ -214,16 +214,20 @@ it 'should validate format', (test) ->
|
||||||
|
|
||||||
test.done()
|
test.done()
|
||||||
|
|
||||||
it 'should validate a field using a custom validator', (test)->
|
it 'should validate a field using a custom validator', (test) ->
|
||||||
|
|
||||||
User.validate 'email', (err)-> err("crash") if @email.length is 0
|
validator = (err) ->
|
||||||
|
err('crash') if @name == 'bad name'
|
||||||
|
|
||||||
|
User.validate 'name', validator, message: crash: 'custom message'
|
||||||
|
|
||||||
user = new User validAttributes
|
user = new User validAttributes
|
||||||
test.ok user.isValid()
|
test.ok user.isValid()
|
||||||
|
|
||||||
user = new User validAttributes
|
user = new User validAttributes
|
||||||
user.email = ""
|
user.name = 'bad name'
|
||||||
test.ok not user.isValid()
|
test.ok not user.isValid(), 'invalid due custom name validator'
|
||||||
|
test.equal user.errors.name[0], 'custom message'
|
||||||
|
|
||||||
test.done()
|
test.done()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue