Skip to content

Commit

Permalink
fix(date service): prevent format calls if date isn't passed (#1291)
Browse files Browse the repository at this point in the history
  • Loading branch information
yggg committed Mar 14, 2019
1 parent b3a586a commit a3d6035
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/framework/date-fns/services/date-fns-date.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ describe('date-fns-date-service', () => {
expect(dateService.parse(date, 'MM.dd.yyyy')).toEqual(new Date(2018, 5, 15));
});

it('should not format if date isn\'t passed', () => {
expect(() => dateService.format(undefined, 'DD.MM.YYYY')).not.toThrow();
expect(dateService.format(undefined, 'DD.MM.YYYY')).toEqual('');
});

describe('service global config', () => {
const SEPARATOR = '_';
const FORMAT = `MM${SEPARATOR}dd${SEPARATOR}yyyy`;
Expand Down
6 changes: 5 additions & 1 deletion src/framework/date-fns/services/date-fns-date.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ export class NbDateFnsDateService extends NbNativeDateService {
}

format(date: Date, format: string): string {
return formatDate(date, format || this.options.format, this.options.formatOptions);
if (date) {
return formatDate(date, format || this.options.format, this.options.formatOptions);
}

return '';
}

parse(date: string, format: string): Date {
Expand Down
5 changes: 5 additions & 0 deletions src/framework/moment/services/moment-date.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ describe('moment-date-service', () => {
expect(parsed.date()).toEqual(15);
});

it('should not format if date isn\'t passed', () => {
expect(() => dateService.format(undefined, 'DD.MM.YYYY')).not.toThrow();
expect(dateService.format(undefined, 'DD.MM.YYYY')).toEqual('');
});

it('should get year end', () => {
const date = moment().year(2018).month(5).date(15);
const yearEnd = dateService.getYearEnd(date);
Expand Down
6 changes: 5 additions & 1 deletion src/framework/moment/services/moment-date.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ export class NbMomentDateService extends NbDateService<Moment> {
}

format(date: Moment, format: string): string {
return date.format(format || this.localeData.defaultFormat);
if (date) {
return date.format(format || this.localeData.defaultFormat);
}

return '';
}

getDate(date: Moment): number {
Expand Down
151 changes: 151 additions & 0 deletions src/framework/theme/components/datepicker/datepicker-adapter.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { TestBed } from '@angular/core/testing';
import { NbCalendarRange, NbDateService } from '@nebular/theme';

import { NbDateAdapterService, NbRangeAdapterService } from './datepicker-adapter';

describe('Date Adapters', () => {
beforeEach(() => {
const mockDateService = {
parse() {},
format() {},
isValidDateString() {},
};

TestBed.configureTestingModule({
providers: [
{ provide: NbDateService, useValue: mockDateService },
NbDateAdapterService,
NbRangeAdapterService,
],
});
});

describe('NbDateAdapterService', () => {
let dateService: NbDateService<Date>;
let adapterService: NbDateAdapterService<Date>;
beforeEach(() => {
adapterService = TestBed.get(NbDateAdapterService);
dateService = TestBed.get(NbDateService);
});

it('should be created', () => {
expect(adapterService).toBeTruthy();
});

it('should use date service to parse date', () => {
const date = '11/11/11';
const format = 'mm/dd/yy';
const parsed = new Date();
const spy = spyOn(dateService, 'parse').and.returnValue(parsed);

expect(adapterService.parse(date, format)).toEqual(parsed);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(date, format);
});

it('should use date service to format date', () => {
const date = new Date();
const format = 'mm/dd/yyyy';
const formatted = 'formatted';
const spy = spyOn(dateService, 'format').and.returnValue(formatted);

expect(adapterService.format(date, format)).toEqual(formatted);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith(date, format);
});

it('should use date service to validate date string', () => {
const date = '11/11/11';
const format = 'mm/dd/yy';
const results = [true, false];
const spy = spyOn(dateService, 'isValidDateString').and.returnValues(...results);

for (let i = 0, callsCount = 0; i < results.length; i++) {
expect(adapterService.isValid(date, format)).toEqual(results[i]);
callsCount++;
expect(spy).toHaveBeenCalledTimes(callsCount);
expect(spy).toHaveBeenCalledWith(date, format);
}
});
});

describe('NbRangeAdapterService', () => {
let dateService: NbDateService<Date>;
let adapterService: NbRangeAdapterService<Date>;
beforeEach(() => {
dateService = TestBed.get(NbDateService);
adapterService = TestBed.get(NbRangeAdapterService);
});

it('should be created', () => {
expect(adapterService).toBeTruthy();
});

it('should use date service to parse date', () => {
const startDate = '11/11/11';
const endDate = '12/11/11';
const date = `${startDate}-${endDate}`;
const format = 'mm/dd/yy';
const expectedStart = new Date();
const expectedEnd = new Date();
const spy = spyOn(dateService, 'parse').and.returnValues(expectedStart, expectedEnd);

const { start: actualStart, end: actualEnd }: NbCalendarRange<Date> = adapterService.parse(date, format);
expect(actualStart).toEqual(expectedStart);
expect(actualEnd).toEqual(expectedEnd);
expect(spy).toHaveBeenCalledTimes(2);
expect(spy.calls.argsFor(0)).toEqual([ startDate, format ]);
expect(spy.calls.argsFor(1)).toEqual([ endDate, format ]);
});

it('should format valid date range', () => {
const range: NbCalendarRange<Date> = { start: new Date(), end: new Date() };
const format = 'mm/dd/yyyy';
const spy = spyOn(dateService, 'isValidDateString').and.returnValues(true, true);

expect(adapterService.format(range, format)).toEqual('undefined - undefined');
expect(spy).toHaveBeenCalledTimes(2);
});

it('should not format if range isn\'t passed', () => {
const spy = spyOn(dateService, 'isValidDateString').and.returnValues(false, false);

expect(adapterService.format(null, '')).toEqual('');
expect(spy).not.toHaveBeenCalled();
});

it('should not format if start date is invalid', () => {
const range: NbCalendarRange<Date> = { start: new Date(), end: new Date() };
const spy = spyOn(dateService, 'isValidDateString').and.returnValue(false);

expect(adapterService.format(range, '')).toEqual('');
expect(spy).toHaveBeenCalledTimes(1);
});

it('should return only start date if end is invalid', () => {
const range: NbCalendarRange<Date> = { start: new Date(), end: new Date() };
const spy = spyOn(dateService, 'isValidDateString').and.returnValues(true, false);

expect(adapterService.format(range, '')).toEqual(undefined);
expect(spy).toHaveBeenCalledTimes(2);
});

it('should use date service to validate date string', () => {
const startDate = '11/11/11';
const endDate = '12/11/11';
const date = `${startDate}-${endDate}`;
const format = 'mm/dd/yy';
const results = [ true, false, true, true ];
const spy = spyOn(dateService, 'isValidDateString').and.returnValues(...results);

for (let i = 0, callsCount = 0; i < results.length - 1; i += 2) {
expect(adapterService.isValid(date, format)).toEqual(results[i] && results[i + 1]);
callsCount += 2;

expect(spy).toHaveBeenCalledTimes(callsCount);
expect(spy.calls.argsFor(i)).toEqual([ startDate, format ]);
expect(spy.calls.argsFor(i + 1)).toEqual([ endDate, format ]);
}
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,16 @@ export class NbRangeAdapterService<D> extends NbDatepickerAdapter<NbCalendarRang
}

const start = this.dateService.format(range.start, format);
const isStartValid = this.dateService.isValidDateString(start, format);

if (!isStartValid) {
return '';
}

const end = this.dateService.format(range.end, format);
const isEndValid = this.dateService.isValidDateString(end, format);

if (end) {
if (isEndValid) {
return `${start} - ${end}`;
} else {
return start;
Expand Down

0 comments on commit a3d6035

Please sign in to comment.