feat: add range validator

pull/4025/head
Arman Ozak 6 years ago
parent bfe5360656
commit bc66979a09

@ -1,4 +1,5 @@
import { FormControl } from '@angular/forms';
import { validateRange } from '../validators';
import { validateCreditCard } from '../validators/credit-card.validator';
import { validateRequired } from '../validators/required.validator';
@ -41,6 +42,42 @@ describe('Validators', () => {
});
});
describe('Range Validator', () => {
test.each`
input | options | expected
${null} | ${undefined} | ${{ min: 0, max: Infinity }}
${undefined} | ${undefined} | ${{ min: 0, max: Infinity }}
${''} | ${undefined} | ${{ min: 0, max: Infinity }}
${0} | ${undefined} | ${null}
${Infinity} | ${undefined} | ${null}
${null} | ${{ minimum: 0 }} | ${{ min: 0, max: Infinity }}
${undefined} | ${{ minimum: 0 }} | ${{ min: 0, max: Infinity }}
${''} | ${{ minimum: 0 }} | ${{ min: 0, max: Infinity }}
${0} | ${{ minimum: 0 }} | ${null}
${2} | ${{ minimum: 3, maximum: 5 }} | ${{ min: 3, max: 5 }}
${3} | ${{ minimum: 3, maximum: 5 }} | ${null}
${5} | ${{ minimum: 3, maximum: 5 }} | ${null}
${6} | ${{ minimum: 3, maximum: 5 }} | ${{ min: 3, max: 5 }}
`(
'should return $expected when input is $input and options are $options',
({ input, options, expected }) => {
const control = new FormControl(input, [validateRange(options)]);
control.markAsDirty({ onlySelf: true });
control.updateValueAndValidity({ onlySelf: true, emitEvent: false });
expect(control.errors).toEqual(expected);
},
);
it('should return null when control is pristine', () => {
const invalidUrl = '';
const control = new FormControl(invalidUrl, [validateRange({ minimum: 3 })]);
// control is not dirty
expect(control.valid).toBe(true);
});
});
describe('Required Validator', () => {
const error = { required: true };

@ -1,11 +1,14 @@
import { Validators } from '@angular/forms';
import { validateCreditCard } from './credit-card.validator';
import { validateRange } from './range.validator';
import { validateRequired } from './required.validator';
export * from './credit-card.validator';
export * from './range.validator';
export * from './required.validator';
export const AbpValidators = {
creditCard: validateCreditCard,
email: () => Validators.email,
range: validateRange,
required: validateRequired,
};

@ -0,0 +1,30 @@
import { AbstractControl, ValidatorFn } from '@angular/forms';
export interface RangeError {
max: number;
min: number;
}
export interface RangeOptions {
maximum?: number;
minimum?: number;
}
export function validateRange({ maximum = Infinity, minimum = 0 }: RangeOptions = {}): ValidatorFn {
return (control: AbstractControl): RangeError | null => {
if (control.pristine) return null;
if (['', null, undefined].indexOf(control.value) > -1) return { min: minimum, max: maximum };
const value = Number(control.value);
return getMinError(value, minimum, maximum) || getMaxError(value, maximum, minimum);
};
}
function getMaxError(value: number, max: number, min: number): RangeError {
return value > max ? { max, min } : null;
}
function getMinError(value: number, min: number, max: number): RangeError {
return value < min ? { min, max } : null;
}
Loading…
Cancel
Save