Commit af4e91ca5188c5a2bc664d9e50fa3f1935dd97c6

Authored by Aresn
Committed by GitHub
2 parents 9eec7f16 c91c30cc

Merge pull request #1674 from SergioCrisostomo/DRY-optimizations

Date utils improvements and specs
src/components/date-picker/util.js
@@ -17,19 +17,7 @@ export const parseDate = function(string, format) { @@ -17,19 +17,7 @@ export const parseDate = function(string, format) {
17 }; 17 };
18 18
19 export const getDayCountOfMonth = function(year, month) { 19 export const getDayCountOfMonth = function(year, month) {
20 - if (month === 3 || month === 5 || month === 8 || month === 10) {  
21 - return 30;  
22 - }  
23 -  
24 - if (month === 1) {  
25 - if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {  
26 - return 29;  
27 - } else {  
28 - return 28;  
29 - }  
30 - }  
31 -  
32 - return 31; 20 + return new Date(year, month + 1, 0).getDate();
33 }; 21 };
34 22
35 export const getFirstDayOfMonth = function(date) { 23 export const getFirstDayOfMonth = function(date) {
@@ -38,48 +26,30 @@ export const getFirstDayOfMonth = function(date) { @@ -38,48 +26,30 @@ export const getFirstDayOfMonth = function(date) {
38 return temp.getDay(); 26 return temp.getDay();
39 }; 27 };
40 28
41 -export const prevMonth = function(src) {  
42 - const year = src.getFullYear();  
43 - const month = src.getMonth();  
44 - const date = src.getDate();  
45 -  
46 - const newYear = month === 0 ? year - 1 : year;  
47 - const newMonth = month === 0 ? 11 : month - 1;  
48 -  
49 - const newMonthDayCount = getDayCountOfMonth(newYear, newMonth);  
50 - if (newMonthDayCount < date) {  
51 - src.setDate(newMonthDayCount); 29 +export const siblingMonth = function(src, diff) {
  30 + const temp = new Date(src); // lets copy it so we don't change the original
  31 + const newMonth = temp.getMonth() + diff;
  32 + const newMonthDayCount = getDayCountOfMonth(temp.getFullYear(), newMonth);
  33 + if (newMonthDayCount < temp.getDate()) {
  34 + temp.setDate(newMonthDayCount);
52 } 35 }
  36 + temp.setMonth(newMonth);
53 37
54 - src.setMonth(newMonth);  
55 - src.setFullYear(newYear); 38 + return temp;
  39 +};
56 40
57 - return new Date(src.getTime()); 41 +export const prevMonth = function(src) {
  42 + return siblingMonth(src, -1);
58 }; 43 };
59 44
60 export const nextMonth = function(src) { 45 export const nextMonth = function(src) {
61 - const year = src.getFullYear();  
62 - const month = src.getMonth();  
63 - const date = src.getDate();  
64 -  
65 - const newYear = month === 11 ? year + 1 : year;  
66 - const newMonth = month === 11 ? 0 : month + 1;  
67 -  
68 - const newMonthDayCount = getDayCountOfMonth(newYear, newMonth);  
69 - if (newMonthDayCount < date) {  
70 - src.setDate(newMonthDayCount);  
71 - }  
72 -  
73 - src.setMonth(newMonth);  
74 - src.setFullYear(newYear);  
75 -  
76 - return new Date(src.getTime()); 46 + return siblingMonth(src, 1);
77 }; 47 };
78 48
79 -export const initTimeDate = function () { 49 +export const initTimeDate = function() {
80 const date = new Date(); 50 const date = new Date();
81 date.setHours(0); 51 date.setHours(0);
82 date.setMinutes(0); 52 date.setMinutes(0);
83 date.setSeconds(0); 53 date.setSeconds(0);
84 return date; 54 return date;
85 -};  
86 \ No newline at end of file 55 \ No newline at end of file
  56 +};
test/unit/specs/date-picker-utils.spec.js 0 → 100644
  1 +const {prevMonth, nextMonth, getDayCountOfMonth} = require('../../../src/components/date-picker/util.js');
  2 +
  3 +// yyyy-mm-dd -> Date
  4 +function dateFromString(str) {
  5 + str = str.split('-').map(Number);
  6 + str[1] = str[1] - 1;
  7 + return new Date(...str);
  8 +}
  9 +
  10 +// Date -> yyyy-mm-dd
  11 +function dateToString(date) {
  12 + return [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-');
  13 +}
  14 +
  15 +describe('DatePicker utility functions', () => {
  16 + const assets = [
  17 + {date: '2030-3-31', prevMonth: '2030-2-28', nextMonth: '2030-4-30', count: 31},
  18 + {date: '2030-3-28', prevMonth: '2030-2-28', nextMonth: '2030-4-28', count: 31},
  19 + {date: '2030-3-1', prevMonth: '2030-2-1', nextMonth: '2030-4-1', count: 31},
  20 + {date: '2030-2-1', prevMonth: '2030-1-1', nextMonth: '2030-3-1', count: 28},
  21 + {date: '2030-1-1', prevMonth: '2029-12-1', nextMonth: '2030-2-1', count: 31},
  22 + {date: '2030-12-31', prevMonth: '2030-11-30', nextMonth: '2031-1-31', count: 31},
  23 + {date: '2030-6-30', prevMonth: '2030-5-30', nextMonth: '2030-7-30', count: 30},
  24 + {date: '2030-5-31', prevMonth: '2030-4-30', nextMonth: '2030-6-30', count: 31},
  25 + {date: '2032-3-31', prevMonth: '2032-2-29', nextMonth: '2032-4-30', count: 31},
  26 + {date: '2032-2-1', prevMonth: '2032-1-1', nextMonth: '2032-3-1', count: 29}
  27 + ];
  28 +
  29 + it('Should behave as pure functions and not change source date', () => {
  30 + const date = new Date(2030, 4, 10);
  31 + const original = date.getMonth();
  32 + const foo = prevMonth(date);
  33 +
  34 + expect(original).to.equal(date.getMonth());
  35 +
  36 + const bar = nextMonth(date);
  37 + expect(original).to.equal(date.getMonth());
  38 + expect(bar.getMonth() - foo.getMonth()).to.equal(2);
  39 + });
  40 +
  41 + it('Should calculate the previous month', () => {
  42 + for (const asset of assets) {
  43 + const date = dateFromString(asset.date);
  44 + const previous = prevMonth(date);
  45 +
  46 + expect(dateToString(previous)).to.equal(asset.prevMonth);
  47 + }
  48 + });
  49 +
  50 + it('Should calculate the next month', () => {
  51 + for (const asset of assets) {
  52 + const date = dateFromString(asset.date);
  53 + const next = nextMonth(date);
  54 +
  55 + expect(dateToString(next)).to.equal(asset.nextMonth);
  56 + }
  57 + });
  58 +
  59 + it('Should calculate the month length', () => {
  60 + for (const asset of assets) {
  61 + const date = dateFromString(asset.date);
  62 + const monthLength = getDayCountOfMonth(date.getFullYear(), date.getMonth());
  63 +
  64 + expect(monthLength).to.equal(asset.count);
  65 + }
  66 + });
  67 +});