From d3f40224b182644c35e500a4d12e418b403e56c8 Mon Sep 17 00:00:00 2001 From: "Philip Sultanescu (Extern)" Date: Thu, 18 May 2017 13:40:28 +0200 Subject: [PATCH] fix(datepicker): minValidator & maxValidation false errors * Min and max dates give false validation errors when selected date is one of the two * Include unit-tests to catch min/max validation errors --- src/lib/datepicker/datepicker-input.ts | 4 +- src/lib/datepicker/datepicker.spec.ts | 78 +++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/lib/datepicker/datepicker-input.ts b/src/lib/datepicker/datepicker-input.ts index 5dc2304436d7..9b676f27f417 100644 --- a/src/lib/datepicker/datepicker-input.ts +++ b/src/lib/datepicker/datepicker-input.ts @@ -130,14 +130,14 @@ export class MdDatepickerInput implements AfterContentInit, ControlValueAcces /** The form control validator for the min date. */ private _minValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { return (!this.min || !control.value || - this._dateAdapter.compareDate(this.min, control.value) < 0) ? + this._dateAdapter.compareDate(this.min, control.value) <= 0) ? null : {'mdDatepickerMin': {'min': this.min, 'actual': control.value}}; } /** The form control validator for the max date. */ private _maxValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => { return (!this.max || !control.value || - this._dateAdapter.compareDate(this.max, control.value) > 0) ? + this._dateAdapter.compareDate(this.max, control.value) >= 0) ? null : {'mdDatepickerMax': {'max': this.max, 'actual': control.value}}; } diff --git a/src/lib/datepicker/datepicker.spec.ts b/src/lib/datepicker/datepicker.spec.ts index 2ee98ec2e4ad..666b34a067e9 100644 --- a/src/lib/datepicker/datepicker.spec.ts +++ b/src/lib/datepicker/datepicker.spec.ts @@ -32,7 +32,7 @@ describe('MdDatepicker', () => { declarations: [ DatepickerWithFilterAndValidation, DatepickerWithFormControl, - DatepickerWithMinAndMax, + DatepickerWithMinAndMaxValidation, DatepickerWithNgModel, DatepickerWithStartAt, DatepickerWithToggle, @@ -413,12 +413,12 @@ describe('MdDatepicker', () => { }); }); - describe('datepicker with min and max dates', () => { - let fixture: ComponentFixture; - let testComponent: DatepickerWithMinAndMax; + describe('datepicker with min and max dates and validation', () => { + let fixture: ComponentFixture; + let testComponent: DatepickerWithMinAndMaxValidation; beforeEach(async(() => { - fixture = TestBed.createComponent(DatepickerWithMinAndMax); + fixture = TestBed.createComponent(DatepickerWithMinAndMaxValidation); fixture.detectChanges(); testComponent = fixture.componentInstance; @@ -433,6 +433,66 @@ describe('MdDatepicker', () => { expect(testComponent.datepicker._minDate).toEqual(new Date(2010, JAN, 1)); expect(testComponent.datepicker._maxDate).toEqual(new Date(2020, JAN, 1)); }); + + it('should mark invalid when value is before min', () => { + testComponent.date = new Date(2009, DEC, 31); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + + expect(fixture.debugElement.query(By.css('input')).nativeElement.classList) + .toContain('ng-invalid'); + }); + }); + + it('should mark invalid when value is after max', () => { + testComponent.date = new Date(2020, JAN, 2); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + + expect(fixture.debugElement.query(By.css('input')).nativeElement.classList) + .toContain('ng-invalid'); + }); + }); + + it('should not mark invalid when value equals min', () => { + testComponent.date = testComponent.datepicker._minDate; + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + + expect(fixture.debugElement.query(By.css('input')).nativeElement.classList) + .not.toContain('ng-invalid'); + }); + }); + + it('should not mark invalid when value equals max', () => { + testComponent.date = testComponent.datepicker._maxDate; + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + + expect(fixture.debugElement.query(By.css('input')).nativeElement.classList) + .not.toContain('ng-invalid'); + }); + }); + + it('should not mark invalid when value is between min and max', () => { + testComponent.date = new Date(2010, JAN, 2); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + fixture.detectChanges(); + + expect(fixture.debugElement.query(By.css('input')).nativeElement.classList) + .not.toContain('ng-invalid'); + }); + }); }); describe('datepicker with filter and validation', () => { @@ -606,14 +666,16 @@ class InputContainerDatepicker { @Component({ template: ` - + + `, }) -class DatepickerWithMinAndMax { +class DatepickerWithMinAndMaxValidation { + @ViewChild('d') datepicker: MdDatepicker; + date: Date; minDate = new Date(2010, JAN, 1); maxDate = new Date(2020, JAN, 1); - @ViewChild('d') datepicker: MdDatepicker; }