Skip to content

Commit

Permalink
fix(datepicker): minValidator & maxValidation false errors (#4649)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Philip Sultanescu authored and tinayuangao committed May 26, 2017
1 parent 1fce545 commit b2c3ed0
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/lib/datepicker/datepicker-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,14 @@ export class MdDatepickerInput<D> 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}};
}

Expand Down
78 changes: 70 additions & 8 deletions src/lib/datepicker/datepicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('MdDatepicker', () => {
declarations: [
DatepickerWithFilterAndValidation,
DatepickerWithFormControl,
DatepickerWithMinAndMax,
DatepickerWithMinAndMaxValidation,
DatepickerWithNgModel,
DatepickerWithStartAt,
DatepickerWithToggle,
Expand Down Expand Up @@ -413,12 +413,12 @@ describe('MdDatepicker', () => {
});
});

describe('datepicker with min and max dates', () => {
let fixture: ComponentFixture<DatepickerWithMinAndMax>;
let testComponent: DatepickerWithMinAndMax;
describe('datepicker with min and max dates and validation', () => {
let fixture: ComponentFixture<DatepickerWithMinAndMaxValidation>;
let testComponent: DatepickerWithMinAndMaxValidation;

beforeEach(async(() => {
fixture = TestBed.createComponent(DatepickerWithMinAndMax);
fixture = TestBed.createComponent(DatepickerWithMinAndMaxValidation);
fixture.detectChanges();

testComponent = fixture.componentInstance;
Expand All @@ -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', () => {
Expand Down Expand Up @@ -606,14 +666,16 @@ class InputContainerDatepicker {

@Component({
template: `
<input [mdDatepicker]="d" [min]="minDate" [max]="maxDate">
<input [mdDatepicker]="d" [(ngModel)]="date" [min]="minDate" [max]="maxDate">
<button [mdDatepickerToggle]="d"></button>
<md-datepicker #d></md-datepicker>
`,
})
class DatepickerWithMinAndMax {
class DatepickerWithMinAndMaxValidation {
@ViewChild('d') datepicker: MdDatepicker<Date>;
date: Date;
minDate = new Date(2010, JAN, 1);
maxDate = new Date(2020, JAN, 1);
@ViewChild('d') datepicker: MdDatepicker<Date>;
}


Expand Down

0 comments on commit b2c3ed0

Please sign in to comment.