fix(forms): fix min and max validator behavior on non-numbers
This commit is contained in:
parent
5a71df0cb3
commit
a222c3e609
@ -64,11 +64,13 @@ export class Validators {
|
|||||||
*/
|
*/
|
||||||
static min(min: number): ValidatorFn {
|
static min(min: number): ValidatorFn {
|
||||||
return (control: AbstractControl): ValidationErrors | null => {
|
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
|
return null; // don't validate empty values to allow optional controls
|
||||||
}
|
}
|
||||||
const value = parseFloat(control.value);
|
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 {
|
static max(max: number): ValidatorFn {
|
||||||
return (control: AbstractControl): ValidationErrors | null => {
|
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
|
return null; // don't validate empty values to allow optional controls
|
||||||
}
|
}
|
||||||
const value = parseFloat(control.value);
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,15 @@ export function main() {
|
|||||||
it('should not error on undefined',
|
it('should not error on undefined',
|
||||||
() => { expect(Validators.min(2)(new FormControl(undefined))).toBeNull(); });
|
() => { expect(Validators.min(2)(new FormControl(undefined))).toBeNull(); });
|
||||||
|
|
||||||
it('should error on non numbers', () => {
|
it('should return null if NaN after parsing',
|
||||||
expect(Validators.min(2)(new FormControl('a'))).toEqual({'min': {'min': 2, 'actual': 'a'}});
|
() => { 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', () => {
|
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}});
|
expect(Validators.min(2)(new FormControl('1'))).toEqual({'min': {'min': 2, 'actual': '1'}});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not error on big values',
|
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',
|
it('should not error on equal values when value is string',
|
||||||
() => { expect(Validators.min(2)(new FormControl('2'))).toBeNull(); });
|
() => { 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', () => {
|
describe('max', () => {
|
||||||
@ -77,14 +92,15 @@ export function main() {
|
|||||||
it('should not error on undefined',
|
it('should not error on undefined',
|
||||||
() => { expect(Validators.max(2)(new FormControl(undefined))).toBeNull(); });
|
() => { expect(Validators.max(2)(new FormControl(undefined))).toBeNull(); });
|
||||||
|
|
||||||
it('should error on non numbers', () => {
|
it('should return null if NaN after parsing',
|
||||||
expect(Validators.max(2)(new FormControl('aaa'))).toEqual({
|
() => { expect(Validators.max(2)(new FormControl('aaa'))).toBeNull(); });
|
||||||
'max': {'max': 2, 'actual': 'aaa'}
|
|
||||||
});
|
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', () => {
|
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}});
|
expect(Validators.max(2)(new FormControl('3'))).toEqual({'max': {'max': 2, 'actual': '3'}});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not error on small values',
|
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',
|
it('should not error on equal values when value is string',
|
||||||
() => { expect(Validators.max(2)(new FormControl('2'))).toBeNull(); });
|
() => { 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(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user