-
Notifications
You must be signed in to change notification settings - Fork 16
Composition of object validators
rsamec edited this page Jul 24, 2014
·
1 revision
You will learn how to create custom validator for your own object with nested structure. You will learn how to composite more custom validators to one main validator.
Let`s image your object has this structure.
interface IData{
Person1:IPerson
Person2:IPerson
}
interface IPerson{
Checked:boolean;
FirstName:string;
LastName:string;
Contact:IContact;
}
interface IContact{
Email:string;
Mobile:IPhone;
FixedLine:IPhone;
}
interface IPhone{
CountryCode:string
Number:string
}
To create validator you have to
- create AbstractValidator IData object
- create AbstractValidator IPerson object
- create AbstractValidator IContact object
- create AbstractValidator IPhone object
- compose these validators to match the object structure with ValidatorFor property
var required = new Validation.RequiredValidator();
var createMainValidator = function(){
var validator = new Validation.AbstractValidator<IData>();
var personValidator = createPersonValidator();
validator.ValidatorFor("Person1",personValidator);
validator.ValidatorFor("Person2",personValidator);
return validator;
}
var createPersonValidator = function() {
var maxLength = new Validation.MaxLengthValidator(15);
var validator = new Validation.AbstractValidator<IPerson>();
validator.RuleFor("FirstName", required);
validator.RuleFor("FirstName", maxLength);
validator.RuleFor("LastName", required);
validator.RuleFor("LastName", maxLength);
var contactValidator = createContactValidator();
validator.ValidatorFor("Contact",contactValidator);
return validator;
}
var createContactValidator = function() {
var validator = new Validation.AbstractValidator<IContact>();
validator.RuleFor("Email", required);
validator.RuleFor("Email", new Validation.MaxLengthValidator(100));
validator.RuleFor("Email", new Validation.EmailValidator());
var phoneValidator = createPhoneValidator();
validator.ValidatorFor("Mobile", phoneValidator);
validator.ValidatorFor("FixedLine", phoneValidator);
return validator;
}
var createPhoneValidator = function() {
var validator = new Validation.AbstractValidator<IPhone>();
validator.RuleFor("CountryCode", required);
validator.RuleFor("CountryCode", new Validation.MaxLengthValidator(3));
validator.RuleFor("Number", required);
validator.RuleFor("Number", new Validation.MaxLengthValidator(9));
var optionsFce = function() {
var deferral = Q.defer();
setTimeout(function () {
deferral.resolve([
{ "value": 420, "text": "CZE" },
{ "value": 22, "text": "USA" },
{ "value": 33, "text": "GER" },
{ "value": 444, "text": "FRA" }
]);
}, 500);
return deferral.promise;
};
var param = new Validation.ParamValidator();
param.ParamId = "countryCodes";
param.Options = optionsFce();
validator.RuleFor("CountryCode", param);
return validator;
}
var mainValidator = createMainValidator();
Use validator to get validation results
this.MainValidator = mainValidator.CreateRule("Person");
//first call sync validation
var result = this.MainValidator.Validate(this.Data);
//verify
if (result.HasErrors){
console.log(result.ErrorMessage);
}
//second - call async validation
var promiseResult = this.MainValidator.ValidateAsync(this.Data);
//verify
promiseResult.then(function (resultAsync) {
if (resultAsync.HasErrors){
console.log(resultAsync.ErrorMessage);
}
}
describe('nested validation rules', function () {
beforeEach(function(){
//setup
var getData = function () {
var contact = {
Email:'[email protected]',
Mobile:{
CountryCode:'CZE',
Number:'736483690'
},
FixedLine:{
CountryCode:'USA',
Number:'736483690'
}
};
return{
Person1: {
Checked:true,
FirstName: "John",
LastName: "Smith",
Contact: contact
},
Person2: {
Checked:true,
FirstName: "Adam",
LastName: "Novak",
Contact: contact
}
}
};
this.Data = getData();
this.MainValidator = mainValidator.CreateRule("Main");
});
it('fill correct data - no errors', function (done) {
//when
//excercise
var result = this.MainValidator.Validate(this.Data);
var promiseResult = this.MainValidator.ValidateAsync(this.Data);
//verify
var selfValidator = this.MainValidator;
promiseResult.then(function (response) {
selfValidator.ValidationResult.LogErrors();
//verify
expect(selfValidator.ValidationResult.HasErrors).to.equal(false);
done();
}).done(null,done);
});
it('fill incorrect data - some errors', function (done) {
//when
//nested property error
this.Data.Person1.Contact.Email = "";
//async nested property error
this.Data.Person1.Contact.Mobile.CountryCode = "BLA";
//excercise
var result = this.MainValidator.Validate(this.Data);
var promiseResult = this.MainValidator.ValidateAsync(this.Data);
//verify
var selfValidator = this.MainValidator;
promiseResult.then(function (response) {
selfValidator.ValidationResult.LogErrors();
//verify
expect(selfValidator.ValidationResult.HasErrors).to.equal(true);
done();
}).done(null,done);
});