fix(forms): fix min and max validator behavior on non-numbers

This commit is contained in:
Kara Erickson 2017-06-07 20:22:23 -07:00 committed by Alex Rickabaugh
parent 5a71df0cb3
commit a222c3e609
2 changed files with 46 additions and 14 deletions

View File

@ -64,11 +64,13 @@ export class Validators {
*/
static min(min: number): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (isEmptyInputValue(control.value)) {
if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
return null; // don't validate empty values to allow optional controls
}
const value = parseFloat(control.value);
return isNaN(value) || value < min ? {'min': {'min': min, 'actual': control.value}} : null;
// Controls with NaN values after parsing should be treated as not having a
// minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
return !isNaN(value) && value < min ? {'min': {'min': min, 'actual': control.value}} : null;
};
}
@ -77,11 +79,13 @@ export class Validators {
*/
static max(max: number): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (isEmptyInputValue(control.value)) {
if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
return null; // don't validate empty values to allow optional controls
}
const value = parseFloat(control.value);
return isNaN(value) || value > max ? {'max': {'max': max, 'actual': control.value}} : null;
// Controls with NaN values after parsing should be treated as not having a
// maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
return !isNaN(value) && value > max ? {'max': {'max': max, 'actual': control.value}} : null;
};
}

View File

@ -49,12 +49,15 @@ export function main() {
it('should not error on undefined',
() => { expect(Validators.min(2)(new FormControl(undefined))).toBeNull(); });
it('should error on non numbers', () => {
expect(Validators.min(2)(new FormControl('a'))).toEqual({'min': {'min': 2, 'actual': 'a'}});
it('should return null if NaN after parsing',
() => { expect(Validators.min(2)(new FormControl('a'))).toBeNull(); });
it('should return a validation error on small values', () => {
expect(Validators.min(2)(new FormControl(1))).toEqual({'min': {'min': 2, 'actual': 1}});
});
it('should error on small values', () => {
expect(Validators.min(2)(new FormControl(1))).toEqual({'min': {'min': 2, 'actual': 1}});
it('should return a validation error on small values converted from strings', () => {
expect(Validators.min(2)(new FormControl('1'))).toEqual({'min': {'min': 2, 'actual': '1'}});
});
it('should not error on big values',
@ -65,6 +68,18 @@ export function main() {
it('should not error on equal values when value is string',
() => { expect(Validators.min(2)(new FormControl('2'))).toBeNull(); });
it('should validate as expected when min value is a string', () => {
expect(Validators.min('2' as any)(new FormControl(1))).toEqual({
'min': {'min': '2', 'actual': 1}
});
});
it('should return null if min value is undefined',
() => { expect(Validators.min(undefined as any)(new FormControl(3))).toBeNull(); });
it('should return null if min value is null',
() => { expect(Validators.min(null as any)(new FormControl(3))).toBeNull(); });
});
describe('max', () => {
@ -77,14 +92,15 @@ export function main() {
it('should not error on undefined',
() => { expect(Validators.max(2)(new FormControl(undefined))).toBeNull(); });
it('should error on non numbers', () => {
expect(Validators.max(2)(new FormControl('aaa'))).toEqual({
'max': {'max': 2, 'actual': 'aaa'}
});
it('should return null if NaN after parsing',
() => { expect(Validators.max(2)(new FormControl('aaa'))).toBeNull(); });
it('should return a validation error on big values', () => {
expect(Validators.max(2)(new FormControl(3))).toEqual({'max': {'max': 2, 'actual': 3}});
});
it('should error on big values', () => {
expect(Validators.max(2)(new FormControl(3))).toEqual({'max': {'max': 2, 'actual': 3}});
it('should return a validation error on big values converted from strings', () => {
expect(Validators.max(2)(new FormControl('3'))).toEqual({'max': {'max': 2, 'actual': '3'}});
});
it('should not error on small values',
@ -95,6 +111,18 @@ export function main() {
it('should not error on equal values when value is string',
() => { expect(Validators.max(2)(new FormControl('2'))).toBeNull(); });
it('should validate as expected when max value is a string', () => {
expect(Validators.max('2' as any)(new FormControl(3))).toEqual({
'max': {'max': '2', 'actual': 3}
});
});
it('should return null if max value is undefined',
() => { expect(Validators.max(undefined as any)(new FormControl(3))).toBeNull(); });
it('should return null if max value is null',
() => { expect(Validators.max(null as any)(new FormControl(3))).toBeNull(); });
});