-
Notifications
You must be signed in to change notification settings - Fork 10
Issue#48 support field validation constraint #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue#48 support field validation constraint #49
Conversation
…nc and async functions. Remove unnecessary declaration of functions when adding field validations in sample react/01 SignupForm
…igned validations. Added test to spy functions for multiple validations added to a field. Updated samples.
lib/src/baseFormValidation.ts
Outdated
} | ||
} | ||
|
||
private addFieldValidationFunctions(fields: { [key: string]: FieldValidationConstraint[] }) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be addFieldsValidationFunctions ?
To follow SRP could it be better to implement something like (I don't like the naming I'm using):
private addFieldsValidationFunctions(...) {
for(let field in fields) {
addFieldValidationFunctions(...)
}
}
private addFieldValidationsFunction() {
const fieldValidationConstraints = fields[field];
if (fieldValidationConstraints instanceof Array) {
addFieldValdationFunction(...)
}
}
(...)
}
lib/lcformvalidation.d.ts
Outdated
|
||
export interface FieldValidationConstraint extends Object { | ||
validator: FieldValidationFunction; | ||
trigger?: { [key: string]: boolean }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are declaring an interface ValidationFilter
below. Do you have to type trigger
with this interface?
return Promise.resolve(fieldValidationResult); | ||
} | ||
|
||
const validationConstraints: ValidationConstraints = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we name this: SignupFormValidationConstraints?
lib/src/baseFormValidation.ts
Outdated
return this; | ||
} | ||
|
||
validateField(vm: any, key: string, value: any, filter?: ValidationFilter): Promise<FieldValidationResult> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to be consistent when naming trigger
or filter
. Select one of this and use it always.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think validationTrigger
is better name because you know when fire validations. What do you think?
interface FormValidation { | ||
validateField(vm: any, key: string, value: any, filter?: any): Promise<FieldValidationResult>; | ||
validateForm(vm: any): Promise<FormValidationResult>; | ||
isValidationInProgress(): boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type => validateField(vm: any, key: string, value: any, filter?: ValidationFilter): Promise;
private propertyMatched(item: any, property: any, globalFilter: any): boolean { | ||
return (globalFilter.hasOwnProperty(property) && | ||
globalFilter[property] == item.filter[property]); | ||
private matchsAnyFilter(fieldValidation: FieldValidation, filters: ValidationFilters) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
matches?
I think matchs is "cerillas"?
lib/src/baseFormValidation.ts
Outdated
} | ||
} | ||
|
||
private parseFormValidations(validationFunctions: FormValidationFunction[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer order methods like we are using:
if (global && global instanceof Array) {
this.parseFormValidations(global);
}
if (fields && typeof fields === 'object') {
this.parseAllFieldsValidations(fields);
}
...
private parseFormValidations(validationFunctions: FormValidationFunction[]) {
.....
}
private parseAllFieldsValidations(fields: { [key: string]: FieldValidationConstraint[] }) {
.....
}
private parseFieldValidations(constraint: string, fieldValidationConstraints: FieldValidationConstraint[]) {
...
}
So, you don't have to scroll down to search what are doing for example parseFormValidations
lib/src/baseFormValidation.ts
Outdated
return this.validationEngine.validateSingleField(vm, key, value, filter); | ||
private addFieldValidation(constraint: string, validationConstraint: FieldValidationConstraint): FormValidation { | ||
this.validationEngine.addFieldValidation( | ||
constraint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this constraint
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we rename to field
?
lib/src/baseFormValidation.ts
Outdated
} | ||
|
||
private addFormValidationFunctions(validationFunctions: FormValidationFunction[]) { | ||
private parseFieldValidations(constraint: string, fieldValidationConstraints: FieldValidationConstraint[]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here same as below
(value: any, vm: any, customParams: any): ValidationResult; | ||
} | ||
|
||
export interface AsyncFieldValidationFunction { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need defined SyncValidationFunction
and AsyncFieldValidationFunction
if we define interface like ValidationResult
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have enough if we only define this?
export interface FieldValidationFunction {
(value: any, vm: any, customParams: any): ValidationResult;
}
|
||
//Assert | ||
expect(promise).to.eventually.be.rejected.notify(done); | ||
expect(promise).to.eventually.be.rejected.and.notify(done); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you earn with and
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just expressivity... I expect the promise to eventually be rejected and notify Chai's "done" method. The promise should call "done" when ends, same as test that does not use chai-as-promised.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks
lib/src/validationEngine.ts
Outdated
isValidationInProgress(): boolean; | ||
validateForm(vm: any): Promise<FormValidationResult>; | ||
triggerFieldValidation(vm: any, key: string, value: any, filter?: any): Promise<FieldValidationResult>; | ||
triggerFieldValidation(vm: any, key: string, value: any, filter?: ValidationFilters, customParams?: Object): Promise<FieldValidationResult>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to validateField
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a method called validateSingleField
that is called by triggerFieldValidation
. Could be a mess rename it validateField
(that calls validateSingleField
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And if we rename like:
triggerFieldValidation
===> validateFiled
validateSingleField
===> triggerFieldValidation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be consistent with fire
and trigger
?? validateSingleField
uses internally validationDispatcher.fireSingleFieldValidations
.
I like your proposal. Should triggerFieldValidation
be triggerFieldValidations
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right, we have to be consistent. I like fireFieldValidations
. What do you think?
lib/src/validationEngine.ts
Outdated
} | ||
|
||
triggerFieldValidation(vm: any, key: string, value: any, filter: any = consts.defaultFilter): Promise<FieldValidationResult> { | ||
triggerFieldValidation(vm: any, key: string, value: any, filter: ValidationFilters = consts.defaultFilter): Promise<FieldValidationResult> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to add here customParams?: Object
parameter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
customParams should be added when you declare your field validation constraint. It is supplied by the validationDispatcher when fires the validation function. Should it be supplied by the action / whatever needs the validation result in runtime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, sorry but I mean, you have declared triggerFieldValidation as triggerFieldValidation(vm: any, key: string, value: any, filter?: ValidationFilters, customParams?: Object)
. So we have to remove from declaration.
See here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad... that's true! I'll check that.
lib/src/validationsDispatcher.ts
Outdated
fireAllFieldsValidations( | ||
vm: Object, | ||
vm: any, | ||
vmKeys: string[], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to pass vmKeys
as parameter instead of create vmKeys inside this method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's because your vm
could have more keys/value that keys which needs to be validated, for instance, suppose we have an entity with 12 members which only 5 needs validation. We need an array of fields with validations to iterate (and that is stored by ValidationEngine). I just figured out when i removed the field-vm-mapping object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I rename it to fieldsWithValidations
or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thanks. It was a bit confusing for me when I read vm
and then vmKeys
.
Maybe some rename like: vmKeysWithValidation
, vmKeysToValidate
, fieldsToValidate
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fieldsToValidate
sounds really good, I'll change it. 👍
if (fieldValidationConstraints instanceof Array) { | ||
fieldValidationConstraints.forEach((fieldValidationConstraint) => { | ||
if (fieldValidationConstraint && typeof fieldValidationConstraint === 'object') { | ||
this.addFieldValidation(constraint, fieldValidationConstraint); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to field
(value: any, vm: any, customParams: any): Promise<FieldValidationResult> |ValidationResult; | ||
} | ||
|
||
export interface AsyncFieldValidationFunction { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this interface
|
||
export interface ValidationConstraints extends Object { | ||
export interface FieldValidationFunction { | ||
(value: any, vm: any, customParams: any): Promise<FieldValidationResult> |ValidationResult; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change method type to only return ValidationResult
This closes #48;