Skip to content

Conversation

@crsanti
Copy link
Member

@crsanti crsanti commented Mar 17, 2017

There was implemented next rules:

  • required: Returns true given true value (for checkboxes) and non-empty string (trimed by default, can be changed with { customParams: { trim: false } }. Returns false for falsy values.
  • minLength: Returns true if given value is string and its length is lesser or equals that given length option in { customParams: { length: <number> } }. null and undefined return true (intended behaviour to treat them as uninitialized values). Returns false if mentioned conditions are not met.
  • maxLength: Returns true if given value is string and its length is greater or equals that given length option in { customParams: { length: <number> } }. null and undefined return true (intended behaviour to treat them as uninitialized values). Returns false if mentioned conditions are not met.
  • email: Returns true if value is a string and matches the RegExp. Otherwise, it returns false.
  • pattern: Returns true if given value matches with the described pattern in { customParams: { pattern: <RegExp | string> } }. If given pattern is a string it will be treated as a full RegExp (NEED REVISION HERE).

function pattern(value: any, vm: any, customParams: PatternParams): FieldValidationResult;
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra space

minLength,
maxLength,
email,
pattern
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add trailing comma

}

export function parseLengthParams(customParams: LengthParams, errorMessage: string) {
const length = customParams.length === null ? NaN : Number(customParams.length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happends if customParams.length is undefined?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have to parse customParams.length to number if LengthParams.lenght field is a number?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is declared as a number in TypeScript but when it is transpiled there is no type checking in runtime.

Copy link
Member Author

@crsanti crsanti Mar 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is undefined it is casted with Number() and getting NaN. I asked for null and did not included undefined because when you do a Number(null) you get 0 instead of NaN and if you do Number(undefined) you get NaN.

return length;
}

interface LengthValidatorFunction {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are you using this interface?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove it

}

// Don't validate non string values
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't use ternary?

}

function isStringLengthValid(value: string, length: number) {
return isNaN(length) ? false : value.length <= length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's necessary check that length isNaN?

What about check value is != null or undefined?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To improve readability is better introduce a carriage return after ? and :

Copy link
Member Author

@crsanti crsanti Mar 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • It's necessary check that length isNaN?
    Yes. Length must be a number.
  • What about check value is != null or undefined?
    isNaN does an implicit Number(<value>).
  • To improve readability is better introduce a carriage return after ? and :.
    Do you mean insert (CR)/LF after return statement like this?:
function isStringLengthValid(value: string, length: number) {
  return isNaN(length) ? false : value.length <= length;

}

That has no sense to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I said something like:

function isStringLengthValid(value: string, length: number) {
  return isNaN(length) ?
       false :
       value.length <= length;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw to improve readability could be write this code like:

function isStringLengthValid(value: string, length: number) {
  return !isNaN(length) &&
       value.length <= length;
}

const validationResult = new FieldValidationResult();

validationResult.succeeded = isValid;
validationResult.key = 'MAX_LENGTH';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: validationResult.type = 'MAX_LENGTH';

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll correct it and its unit tests.

const validationResult = new FieldValidationResult();
validationResult.errorMessage = isValid ? '' : `The value provided must have at least ${length} characters.`;
validationResult.succeeded = isValid;
validationResult.key = 'MIN_LENGTH';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: validationResult.type = 'MIN_LENGTH';

}

function isStringLengthValid(value: string, length: number) {
return value.length >= length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to check is value != null or undefined before access length property

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is called before isLengthValid that already checks if value is a string.

pattern: string | RegExp;
}

const BAD_PARAMETER = 'FieldValidationError: pattern option for pattern validation is mandatory. Example: { pattern: /\d+/ }.';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add carriage return afer this const like other rules

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok! 👍

}

function parsePattern({ pattern }: PatternParams): RegExp {
if (pattern === undefined || pattern === null) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this condition equals to:

if (!pattern) {
 ....
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not true for "", false or 0 values. I tried to avoid RegExp like /null/ I'll change that to:

if (typeof pattern === 'boolean' || pattern === null) {
    throw new Error(BAD_PARAMETER);
  }
  return getRegExp(pattern);

to avoid /true/ and /false/ too (with a comment).


function getRegExp(pattern) {
if (typeof pattern === 'string') {
return new RegExp(`^${pattern}$`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have to force to ^...$? User could pass a pattern like:

{
  pattern: 'abc$'
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add an flag in customParams to enable this feature or disable it. We need discussion about this behavior.

if (pattern instanceof RegExp) {
return pattern;
}
return new RegExp(pattern);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is this case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User is allowed to enter a RegExp or string to use the pattern validator.

const validationResult = new FieldValidationResult();
const isValid = isValidField(value, Boolean(customParams.trim));
if (!isValid) {
validationResult.errorMessage = 'Please fill in this mandatory field.';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't use ternary as other rules?

validationResult.errorMessage = isValid? '' :  'Please fill in this mandatory field.';

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change it.


function isValidField(value, trim: boolean): boolean {
if (typeof value === 'string') {
return isStringValid(value, trim);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid multiples returns. You can write this code like:

function isValidField(value, trim: boolean): boolean {
  return isInitialized(value) &&
       isString(value) &&
       isStringValid(value, trim);
}


length: number,
validatorFn: (value: string, length: number) => boolean
): boolean {
return typeof value === 'string' ? validatorFn(value, length) : true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return typeof value === 'string' ?
validatorFn(value, length) :
true;


it('should return false if value is undefined', () => {
// Arrange
const value = null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: const value = undefined?

crsanti added 2 commits March 21, 2017 09:22
Added typings on returned values by some functions.
@crsanti crsanti merged commit e82a6c7 into master Mar 21, 2017
@crsanti crsanti deleted the issue#50-validation-rules branch March 21, 2017 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants