2
0
mirror of https://github.com/tenrok/vue2-datepicker.git synced 2026-06-19 23:20:35 +03:00

refactor: 3.0

This commit is contained in:
mengxiong10
2019-11-10 17:47:30 +08:00
parent 72024440d7
commit 4875dc6b3d
165 changed files with 23248 additions and 21723 deletions
@@ -0,0 +1,222 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`CalendarPanel prop: type=date 1`] = `
<div
class="mx-calendar mx-calendar-panel-date"
>
<div
class="mx-calendar-header"
>
<button
class="mx-btn mx-btn-text mx-btn-icon-double-left"
>
<i
class="mx-icon-double-left"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-left"
>
<i
class="mx-icon-left"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-double-right"
>
<i
class="mx-icon-double-right"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-right"
>
<i
class="mx-icon-right"
/>
</button>
<span
class="mx-calendar-header-label"
>
<button
class="mx-btn mx-btn-text mx-btn-current-month"
>
Oct
</button>
<button
class="mx-btn mx-btn-text mx-btn-current-year"
>
2019
</button>
</span>
</div>
<div
class="mx-calendar-content"
>
<table-year-stub
decade="2010"
getcellclasses="function () { [native code] }"
style="display: none;"
/>
<table-month-stub
getcellclasses="function () { [native code] }"
style="display: none;"
/>
<table-date-stub
calendarmonth="9"
calendaryear="2019"
getcellclasses="function () { [native code] }"
getrowclasses="function () { [native code] }"
titleformat="YYYY-MM-DD"
/>
</div>
</div>
`;
exports[`CalendarPanel prop: type=month 1`] = `
<div
class="mx-calendar mx-calendar-panel-month"
>
<div
class="mx-calendar-header"
>
<button
class="mx-btn mx-btn-text mx-btn-icon-double-left"
>
<i
class="mx-icon-double-left"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-left"
style="display: none;"
>
<i
class="mx-icon-left"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-double-right"
>
<i
class="mx-icon-double-right"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-right"
style="display: none;"
>
<i
class="mx-icon-right"
/>
</button>
<span
class="mx-calendar-header-label"
>
<button
class="mx-btn mx-btn-text"
>
2019
</button>
</span>
</div>
<div
class="mx-calendar-content"
>
<table-year-stub
decade="2010"
getcellclasses="function () { [native code] }"
style="display: none;"
/>
<table-month-stub
getcellclasses="function () { [native code] }"
/>
<!---->
</div>
</div>
`;
exports[`CalendarPanel prop: type=year 1`] = `
<div
class="mx-calendar mx-calendar-panel-year"
>
<div
class="mx-calendar-header"
>
<button
class="mx-btn mx-btn-text mx-btn-icon-double-left"
>
<i
class="mx-icon-double-left"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-left"
style="display: none;"
>
<i
class="mx-icon-left"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-double-right"
>
<i
class="mx-icon-double-right"
/>
</button>
<button
class="mx-btn mx-btn-text mx-btn-icon-right"
style="display: none;"
>
<i
class="mx-icon-right"
/>
</button>
<span
class="mx-calendar-header-label"
>
<span>
2010 ~ 2019
</span>
</span>
</div>
<div
class="mx-calendar-content"
>
<table-year-stub
decade="2010"
getcellclasses="function () { [native code] }"
/>
<!---->
<!---->
</div>
</div>
`;
@@ -0,0 +1,144 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`DatePicker prop: attrs of input 1`] = `
<div
class="mx-datepicker"
>
<div
class="mx-input-wrapper"
>
<input
autocomplete="off"
class="test"
name="test"
placeholder="test placeholder"
type="number"
/>
<!---->
<i
class="mx-icon-calendar"
>
<icon-calendar-stub />
</i>
</div>
<popup-stub
appendtobody="true"
>
<!---->
<div
class="mx-datepicker-content-wrapper"
>
<!---->
<div
class="mx-datepicker-content"
>
<div />
</div>
</div>
<!---->
</popup-stub>
</div>
`;
exports[`DatePicker prop: clearable 1`] = `
<div
class="mx-datepicker"
>
<div
class="mx-input-wrapper"
>
<input
autocomplete="off"
class="mx-input"
name="date"
placeholder=""
type="text"
/>
<!---->
<i
class="mx-icon-calendar"
>
<icon-calendar-stub />
</i>
</div>
<popup-stub
appendtobody="true"
>
<!---->
<div
class="mx-datepicker-content-wrapper"
>
<!---->
<div
class="mx-datepicker-content"
>
<div />
</div>
</div>
<!---->
</popup-stub>
</div>
`;
exports[`DatePicker prop: editable 1`] = `
<div
class="mx-datepicker"
>
<div
class="mx-input-wrapper"
>
<input
autocomplete="off"
class="mx-input"
name="date"
placeholder=""
readonly="readonly"
type="text"
/>
<i
class="mx-icon-clear"
>
<icon-close-stub />
</i>
<i
class="mx-icon-calendar"
>
<icon-calendar-stub />
</i>
</div>
<popup-stub
appendtobody="true"
>
<!---->
<div
class="mx-datepicker-content-wrapper"
>
<!---->
<div
class="mx-datepicker-content"
>
<div />
</div>
</div>
<!---->
</popup-stub>
</div>
`;
@@ -0,0 +1,453 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TableDate corrent render 1`] = `
<table
class="mx-table mx-table-date"
firstdayofweek="1"
>
<thead>
<tr>
<!---->
<th>
Su
</th>
<th>
Mo
</th>
<th>
Tu
</th>
<th>
We
</th>
<th>
Th
</th>
<th>
Fr
</th>
<th>
Sa
</th>
</tr>
</thead>
<tbody>
<tr
class="mx-date-row"
>
<!---->
<td
class="cell"
data-day="-1"
title="29/09/2019"
>
<div>
29
</div>
</td>
<td
class="cell"
data-day="0"
title="30/09/2019"
>
<div>
30
</div>
</td>
<td
class="cell"
data-day="1"
title="01/10/2019"
>
<div>
1
</div>
</td>
<td
class="cell"
data-day="2"
title="02/10/2019"
>
<div>
2
</div>
</td>
<td
class="cell"
data-day="3"
title="03/10/2019"
>
<div>
3
</div>
</td>
<td
class="cell"
data-day="4"
title="04/10/2019"
>
<div>
4
</div>
</td>
<td
class="cell"
data-day="5"
title="05/10/2019"
>
<div>
5
</div>
</td>
</tr>
<tr
class="mx-date-row"
>
<!---->
<td
class="cell"
data-day="6"
title="06/10/2019"
>
<div>
6
</div>
</td>
<td
class="cell"
data-day="7"
title="07/10/2019"
>
<div>
7
</div>
</td>
<td
class="cell"
data-day="8"
title="08/10/2019"
>
<div>
8
</div>
</td>
<td
class="cell"
data-day="9"
title="09/10/2019"
>
<div>
9
</div>
</td>
<td
class="cell"
data-day="10"
title="10/10/2019"
>
<div>
10
</div>
</td>
<td
class="cell"
data-day="11"
title="11/10/2019"
>
<div>
11
</div>
</td>
<td
class="cell"
data-day="12"
title="12/10/2019"
>
<div>
12
</div>
</td>
</tr>
<tr
class="mx-date-row"
>
<!---->
<td
class="cell"
data-day="13"
title="13/10/2019"
>
<div>
13
</div>
</td>
<td
class="cell"
data-day="14"
title="14/10/2019"
>
<div>
14
</div>
</td>
<td
class="cell"
data-day="15"
title="15/10/2019"
>
<div>
15
</div>
</td>
<td
class="cell"
data-day="16"
title="16/10/2019"
>
<div>
16
</div>
</td>
<td
class="cell"
data-day="17"
title="17/10/2019"
>
<div>
17
</div>
</td>
<td
class="cell"
data-day="18"
title="18/10/2019"
>
<div>
18
</div>
</td>
<td
class="cell"
data-day="19"
title="19/10/2019"
>
<div>
19
</div>
</td>
</tr>
<tr
class="mx-date-row"
>
<!---->
<td
class="cell"
data-day="20"
title="20/10/2019"
>
<div>
20
</div>
</td>
<td
class="cell"
data-day="21"
title="21/10/2019"
>
<div>
21
</div>
</td>
<td
class="cell"
data-day="22"
title="22/10/2019"
>
<div>
22
</div>
</td>
<td
class="cell"
data-day="23"
title="23/10/2019"
>
<div>
23
</div>
</td>
<td
class="cell"
data-day="24"
title="24/10/2019"
>
<div>
24
</div>
</td>
<td
class="cell"
data-day="25"
title="25/10/2019"
>
<div>
25
</div>
</td>
<td
class="cell"
data-day="26"
title="26/10/2019"
>
<div>
26
</div>
</td>
</tr>
<tr
class="mx-date-row"
>
<!---->
<td
class="cell"
data-day="27"
title="27/10/2019"
>
<div>
27
</div>
</td>
<td
class="cell"
data-day="28"
title="28/10/2019"
>
<div>
28
</div>
</td>
<td
class="cell"
data-day="29"
title="29/10/2019"
>
<div>
29
</div>
</td>
<td
class="cell"
data-day="30"
title="30/10/2019"
>
<div>
30
</div>
</td>
<td
class="cell"
data-day="31"
title="31/10/2019"
>
<div>
31
</div>
</td>
<td
class="cell"
data-day="32"
title="01/11/2019"
>
<div>
1
</div>
</td>
<td
class="cell"
data-day="33"
title="02/11/2019"
>
<div>
2
</div>
</td>
</tr>
<tr
class="mx-date-row"
>
<!---->
<td
class="cell"
data-day="34"
title="03/11/2019"
>
<div>
3
</div>
</td>
<td
class="cell"
data-day="35"
title="04/11/2019"
>
<div>
4
</div>
</td>
<td
class="cell"
data-day="36"
title="05/11/2019"
>
<div>
5
</div>
</td>
<td
class="cell"
data-day="37"
title="06/11/2019"
>
<div>
6
</div>
</td>
<td
class="cell"
data-day="38"
title="07/11/2019"
>
<div>
7
</div>
</td>
<td
class="cell"
data-day="39"
title="08/11/2019"
>
<div>
8
</div>
</td>
<td
class="cell"
data-day="40"
title="09/11/2019"
>
<div>
9
</div>
</td>
</tr>
</tbody>
</table>
`;
@@ -0,0 +1,119 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TableMonth correct render 1`] = `
<table
class="mx-table mx-table-month"
getclasses="month => {
if (month === 9) {
return 'active';
}
return '';
}"
>
<tr>
<td
class="cell"
data-month="0"
>
<div>
Jan
</div>
</td>
<td
class="cell"
data-month="1"
>
<div>
Feb
</div>
</td>
<td
class="cell"
data-month="2"
>
<div>
Mar
</div>
</td>
</tr>
<tr>
<td
class="cell"
data-month="3"
>
<div>
Apr
</div>
</td>
<td
class="cell"
data-month="4"
>
<div>
May
</div>
</td>
<td
class="cell"
data-month="5"
>
<div>
Jun
</div>
</td>
</tr>
<tr>
<td
class="cell"
data-month="6"
>
<div>
Jul
</div>
</td>
<td
class="cell"
data-month="7"
>
<div>
Aug
</div>
</td>
<td
class="cell"
data-month="8"
>
<div>
Sep
</div>
</td>
</tr>
<tr>
<td
class="cell"
data-month="9"
>
<div>
Oct
</div>
</td>
<td
class="cell"
data-month="10"
>
<div>
Nov
</div>
</td>
<td
class="cell"
data-month="11"
>
<div>
Dec
</div>
</td>
</tr>
</table>
`;
@@ -0,0 +1,98 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TableYear decade=2010 1`] = `
<table
class="mx-table mx-table-year"
>
<tr>
<td
class="cell"
data-year="2010"
>
<div>
2010
</div>
</td>
<td
class="cell"
data-year="2011"
>
<div>
2011
</div>
</td>
</tr>
<tr>
<td
class="cell"
data-year="2012"
>
<div>
2012
</div>
</td>
<td
class="cell"
data-year="2013"
>
<div>
2013
</div>
</td>
</tr>
<tr>
<td
class="cell"
data-year="2014"
>
<div>
2014
</div>
</td>
<td
class="cell"
data-year="2015"
>
<div>
2015
</div>
</td>
</tr>
<tr>
<td
class="cell"
data-year="2016"
>
<div>
2016
</div>
</td>
<td
class="cell"
data-year="2017"
>
<div>
2017
</div>
</td>
</tr>
<tr>
<td
class="cell"
data-year="2018"
>
<div>
2018
</div>
</td>
<td
class="cell"
data-year="2019"
>
<div>
2019
</div>
</td>
</tr>
</table>
`;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,328 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TimeRange render: correct classes of the columns 1`] = `
<div
class="mx-range-wrapper"
>
<div
class="mx-time"
>
<!---->
<div
class="mx-time-content"
>
<div
class="mx-time-columns"
>
<div
class="mx-scrollbar mx-time-column"
style="position: relative; overflow: hidden;"
>
<div
class="mx-scrollbar-wrap"
style="overflow: hidden scroll; height: 100%; margin-right: -0px;"
>
<ul
data-type="hour"
>
<li
class="cell"
data-value="1570120200000"
>
12
</li>
<li
class="cell"
data-value="1570127400000"
>
02
</li>
<li
class="cell"
data-value="1570134600000"
>
04
</li>
<li
class="cell"
data-value="1570141800000"
>
06
</li>
<li
class="cell active"
data-value="1570149000000"
>
08
</li>
<li
class="cell"
data-value="1570156200000"
>
10
</li>
</ul>
</div>
<div
class="mx-scrollbar-track"
>
<div
class="mx-scrollbar-thumb"
/>
</div>
</div>
<div
class="mx-scrollbar mx-time-column"
style="position: relative; overflow: hidden;"
>
<div
class="mx-scrollbar-wrap"
style="overflow: hidden scroll; height: 100%; margin-right: -0px;"
>
<ul
data-type="minute"
>
<li
class="cell"
data-value="1570147200000"
>
00
</li>
<li
class="cell active"
data-value="1570149000000"
>
30
</li>
</ul>
</div>
<div
class="mx-scrollbar-track"
>
<div
class="mx-scrollbar-thumb"
/>
</div>
</div>
<div
class="mx-scrollbar mx-time-column"
style="position: relative; overflow: hidden;"
>
<div
class="mx-scrollbar-wrap"
style="overflow: hidden scroll; height: 100%; margin-right: -0px;"
>
<ul
data-type="ampm"
>
<li
class="cell active"
data-value="1570149000000"
>
AM
</li>
<li
class="cell"
data-value="1570192200000"
>
PM
</li>
</ul>
</div>
<div
class="mx-scrollbar-track"
>
<div
class="mx-scrollbar-thumb"
/>
</div>
</div>
</div>
</div>
</div>
<div
class="mx-time"
>
<!---->
<div
class="mx-time-content"
>
<div
class="mx-time-columns"
>
<div
class="mx-scrollbar mx-time-column"
style="position: relative; overflow: hidden;"
>
<div
class="mx-scrollbar-wrap"
style="overflow: hidden scroll; height: 100%; margin-right: -0px;"
>
<ul
data-type="hour"
>
<li
class="cell"
data-value="1570163400000"
>
12
</li>
<li
class="cell"
data-value="1570170600000"
>
02
</li>
<li
class="cell"
data-value="1570177800000"
>
04
</li>
<li
class="cell active"
data-value="1570185000000"
>
06
</li>
<li
class="cell"
data-value="1570192200000"
>
08
</li>
<li
class="cell"
data-value="1570199400000"
>
10
</li>
</ul>
</div>
<div
class="mx-scrollbar-track"
>
<div
class="mx-scrollbar-thumb"
/>
</div>
</div>
<div
class="mx-scrollbar mx-time-column"
style="position: relative; overflow: hidden;"
>
<div
class="mx-scrollbar-wrap"
style="overflow: hidden scroll; height: 100%; margin-right: -0px;"
>
<ul
data-type="minute"
>
<li
class="cell"
data-value="1570183200000"
>
00
</li>
<li
class="cell active"
data-value="1570185000000"
>
30
</li>
</ul>
</div>
<div
class="mx-scrollbar-track"
>
<div
class="mx-scrollbar-thumb"
/>
</div>
</div>
<div
class="mx-scrollbar mx-time-column"
style="position: relative; overflow: hidden;"
>
<div
class="mx-scrollbar-wrap"
style="overflow: hidden scroll; height: 100%; margin-right: -0px;"
>
<ul
data-type="ampm"
>
<li
class="cell disabled"
data-value="1570141800000"
>
AM
</li>
<li
class="cell active"
data-value="1570185000000"
>
PM
</li>
</ul>
</div>
<div
class="mx-scrollbar-track"
>
<div
class="mx-scrollbar-thumb"
/>
</div>
</div>
</div>
</div>
</div>
</div>
`;
+157
View File
@@ -0,0 +1,157 @@
import { mount, shallowMount } from '@vue/test-utils';
import CalendarPanel from '../src/calendar/calendar-panel';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('CalendarPanel', () => {
it('feat: type = date, should emit select when click date', () => {
wrapper = mount(CalendarPanel, {
propsData: {
value: new Date(2019, 9, 4),
},
});
const tds = wrapper.findAll('.mx-table-date td');
tds.at(0).trigger('click');
expect(wrapper.emitted().select[0][0]).toEqual(new Date(2019, 8, 29));
});
it('feat: type = month, should emit event when click month', () => {
wrapper = mount(CalendarPanel, {
propsData: {
type: 'month',
defaultValue: new Date(2019, 9, 1),
},
});
const tds = wrapper.findAll('.mx-table-month td > div');
tds.at(0).trigger('click');
expect(wrapper.emitted().select[0][0]).toEqual(new Date(2019, 0, 1));
});
it('feat: type = year, should emit event when click year', () => {
wrapper = mount(CalendarPanel, {
propsData: {
type: 'year',
defaultValue: new Date(2019, 9, 1),
},
});
const tds = wrapper.findAll('.mx-table-year td > div');
tds.at(0).trigger('click');
expect(wrapper.emitted().select[0][0]).toEqual(new Date(2010, 0));
});
it('feat: active class', () => {
wrapper = mount(CalendarPanel);
const td = wrapper.find('.mx-table-date td:nth-child(6)');
expect(td.classes()).not.toContain('active');
wrapper.setProps({ value: new Date(2019, 9, 4) });
expect(td.classes()).toContain('active');
});
const renderType = type => {
it(`prop: type=${type}`, () => {
wrapper = shallowMount(CalendarPanel, {
propsData: {
type,
value: new Date(2019, 9, 1, 10),
},
});
expect(wrapper.element).toMatchSnapshot();
});
};
['date', 'month', 'year'].forEach(renderType);
it('prop: disabledDate', () => {
const disabledDate = date => {
return date < new Date(2019, 9, 1) || date > new Date(2019, 9, 20);
};
wrapper = mount(CalendarPanel, {
propsData: {
value: new Date(2019, 9, 4),
disabledDate,
},
});
const tds = wrapper.findAll('.mx-table-date td');
for (let i = 0; i < 42; i++) {
const td = tds.at(i);
const classes = td.classes();
if (i < 2 || i > 21) {
expect(classes).toContain('disabled');
} else {
expect(classes).not.toContain('disabled');
}
}
tds.at(1).trigger('click');
expect(wrapper.emitted().select).toBeUndefined();
});
it('feat: click prev/next month', () => {
wrapper = shallowMount(CalendarPanel);
const nextBtn = wrapper.find('.mx-btn-icon-right');
const lastBtn = wrapper.find('.mx-btn-icon-left');
const { vm } = wrapper;
let count = 12;
while (count--) {
const oldYear = vm.calendarYear;
const oldMonth = vm.calendarMonth;
nextBtn.trigger('click');
const newYear = vm.calendarYear;
const newMonth = vm.calendarMonth;
if (oldMonth === 11) {
expect(newMonth).toBe(0);
expect(newYear).toBe(oldYear + 1);
} else {
expect(newMonth).toBe(oldMonth + 1);
expect(newYear).toBe(oldYear);
}
}
count = 12;
while (count--) {
const oldYear = vm.calendarYear;
const oldMonth = vm.calendarMonth;
lastBtn.trigger('click');
const newYear = vm.calendarYear;
const newMonth = vm.calendarMonth;
if (oldMonth === 0) {
expect(newMonth).toBe(11);
expect(newYear).toBe(oldYear - 1);
} else {
expect(newMonth).toBe(oldMonth - 1);
expect(newYear).toBe(oldYear);
}
}
});
it('feat: click prev/next year', () => {
wrapper = shallowMount(CalendarPanel, {
propsData: {
value: new Date(2018, 4, 5),
},
});
const nextBtn = wrapper.find('.mx-btn-icon-double-right');
const lastBtn = wrapper.find('.mx-btn-icon-double-left');
const yearBtn = wrapper.find('.mx-btn-current-year');
const { vm } = wrapper;
const oldYear = vm.calendarYear;
expect(oldYear).toBe(2018);
nextBtn.trigger('click');
let newYear = vm.calendarYear;
expect(newYear).toBe(2019);
lastBtn.trigger('click');
newYear = vm.calendarYear;
expect(newYear).toBe(oldYear);
// 年视图测试
yearBtn.trigger('click');
expect(vm.panel).toBe('year');
expect(vm.calendarDecade).toBe(2010);
nextBtn.trigger('click');
expect(vm.calendarDecade).toBe(2020);
lastBtn.trigger('click');
lastBtn.trigger('click');
expect(vm.calendarDecade).toBe(2000);
});
});
+66
View File
@@ -0,0 +1,66 @@
import { mount } from '@vue/test-utils';
import flushPromises from 'flush-promises';
import CalendarRange from '../src/calendar/calendar-range';
import CalendarPanel from '../src/calendar/calendar-panel';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('CalendarRange', () => {
it('feat: correct classes', () => {
wrapper = mount(CalendarRange, {
sync: false,
propsData: {
value: [new Date(2019, 9, 30), new Date(2019, 10, 2)],
},
});
const activeTds = wrapper.findAll('.mx-table-date .active');
const rangeTds = wrapper.findAll('.mx-table-date .in-range');
expect(activeTds.length).toBe(2);
expect(activeTds.at(0).text()).toBe('30');
expect(activeTds.at(1).text()).toBe('2');
expect(rangeTds.length).toBe(2);
expect(rangeTds.at(0).text()).toBe('31');
expect(rangeTds.at(1).text()).toBe('1');
});
it('feat: click range', async () => {
wrapper = mount(CalendarRange, {
sync: false,
propsData: {
defaultValue: new Date(2019, 9, 1),
},
});
expect(wrapper.vm.calendars).toEqual([new Date(2019, 9, 1), new Date(2019, 10, 1)]);
const tds = wrapper.findAll('.mx-table-date td');
tds.at(2).trigger('click');
await flushPromises();
expect(wrapper.emitted().select).toBeUndefined();
tds.at(8).trigger('click');
await flushPromises();
expect(wrapper.emitted().select[0][0]).toEqual([new Date(2019, 9, 1), new Date(2019, 9, 7)]);
});
it('feat: calendars min gap', async () => {
wrapper = mount(CalendarRange, {
sync: false,
propsData: {
defaultValue: new Date(2019, 6, 1),
},
});
const panels = wrapper.findAll(CalendarPanel);
const startPanel = panels.at(0);
const endPanel = panels.at(1);
startPanel.find('.mx-btn-icon-right').trigger('click');
await flushPromises();
expect(wrapper.vm.calendars).toEqual([new Date(2019, 7, 1), new Date(2019, 8, 1)]);
endPanel.find('.mx-btn-icon-left').trigger('click');
await flushPromises();
expect(wrapper.vm.calendars).toEqual([new Date(2019, 6, 1), new Date(2019, 7, 1)]);
});
});
+277
View File
@@ -0,0 +1,277 @@
import { shallowMount, createWrapper, mount } from '@vue/test-utils';
import { format, parse } from 'date-fns';
import DatePicker from '../src/date-picker.vue';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('DatePicker', () => {
it('feat: open and close the popup', () => {
wrapper = mount(DatePicker, {
attachToDocument: true,
});
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(false);
// expect click input should show the popup
const input = wrapper.find('input');
input.trigger('click');
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(true);
// expect click out side should hide the popup
const bodyWrapper = createWrapper(document.body);
bodyWrapper.trigger('mousedown');
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(false);
// expect focus input should show the popop
input.trigger('focus');
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(true);
// expoce keydown tab should hide the popup
input.trigger('keydown.tab');
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(false);
});
it('feat: should init panel and calendar when reopen', () => {
wrapper = mount(DatePicker, {
propsData: {
defaultValue: new Date(2019, 9, 1),
open: true,
},
});
const yearBtn = wrapper.find('.mx-btn-current-year');
yearBtn.trigger('click');
// change to year panel
expect(wrapper.find('.mx-calendar-panel-year').exists()).toBe(true);
wrapper.setProps({ open: false });
wrapper.setProps({ open: true });
expect(wrapper.find('.mx-calendar-panel-year').exists()).toBe(false);
});
it('prop: open', () => {
wrapper = mount(DatePicker, {
propsData: {
open: false,
},
});
const { vm } = wrapper;
vm.openPopup();
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(false);
wrapper.setProps({ open: true });
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(true);
vm.closePopup();
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(true);
const emitted = wrapper.emitted();
expect(emitted['update:open'][0][0]).toBe(true);
expect(emitted['update:open'][1][0]).toBe(false);
});
it('prop: disabled(should not show the popup)', () => {
wrapper = mount(DatePicker, {
propsData: {
disabled: true,
},
});
const input = wrapper.find('input');
expect(input.attributes('disabled')).toBe('disabled');
input.trigger('click');
expect(wrapper.find('.mx-datepicker-popup').exists()).toBe(false);
});
it('prop: clearable', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
value: new Date(2019, 4, 10),
defaultValue: new Date(2019, 4, 10),
clearable: false,
},
// calendar-panel: default-value="Fri May 10 2019 00:00:00 GMT+0800 (CST)"
// Exclude the impact of timezone
scopedSlots: {
content: '<div></div>',
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('prop: editable', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
value: new Date(2019, 4, 10),
defaultValue: new Date(2019, 4, 10),
editable: false,
},
scopedSlots: {
content: '<div></div>',
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('prop: attrs of input', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
defaultValue: new Date(2019, 4, 10),
placeholder: 'test placeholder',
inputClass: 'test',
inputAttr: {
type: 'number',
name: 'test',
},
},
scopedSlots: {
content: '<div></div>',
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('prop: format', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
format: 'YYYY/MM/DD',
value: new Date(2019, 9, 10),
},
});
const input = wrapper.find('input').element;
expect(input.value).toBe('2019/10/10');
});
it('prop: custom format', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
valueType: 'format',
value: '13/10/2019',
format: {
stringify(date) {
return format(date, 'dd/MM/yyyy');
},
parse(value) {
return parse(value, 'dd/MM/yyyy', new Date());
},
},
},
});
const input = wrapper.find('input').element;
expect(input.value).toBe('13/10/2019');
});
it('prop: valueType', () => {
const value = new Date(2019, 9, 20);
const emitValue = new Date(2019, 9, 22);
wrapper = shallowMount(DatePicker, {
propsData: {
value,
format: 'YYYY/MM/DD',
},
});
const { vm } = wrapper;
expect(vm.text).toBe('2019/10/20');
vm.emitValue(emitValue);
wrapper.setProps({ valueType: 'format', value: '2019/10/20' });
expect(vm.text).toBe('2019/10/20');
vm.emitValue(emitValue);
wrapper.setProps({ valueType: 'timestamp', value: value.getTime() });
expect(vm.text).toBe('2019/10/20');
vm.emitValue(emitValue);
wrapper.setProps({ valueType: 'DD/MM/YYYY', value: '20/10/2019' });
expect(vm.text).toBe('2019/10/20');
vm.emitValue(emitValue);
const emitted = wrapper.emitted();
expect(emitted.input).toEqual([
[emitValue],
['2019/10/22'],
[emitValue.getTime()],
['22/10/2019'],
]);
});
it('prop: shortcut', () => {
const date = new Date(2019, 4, 10);
wrapper = shallowMount(DatePicker, {
propsData: {
open: true,
valueType: 'YYYY/MM/DD',
shortcuts: [
{
text: 'Today',
onClick() {
return date;
},
},
],
},
});
const btn = wrapper.find('.mx-btn-shortcut');
btn.trigger('click');
const emitted = wrapper.emitted();
expect(emitted.input).toEqual([['2019/05/10']]);
});
it('prop: popupClass', () => {
wrapper = mount(DatePicker, {
propsData: {
open: true,
popupClass: 'test',
},
});
const popup = wrapper.find('.mx-datepicker-popup');
expect(popup.classes()).toContain('test');
});
it('prop: popupStyle', () => {
wrapper = mount(DatePicker, {
propsData: {
open: true,
popupStyle: {
color: 'red',
},
},
});
const popup = wrapper.find('.mx-datepicker-popup');
expect(popup.element.style.color).toBe('red');
});
it('prop: confirm', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
confirm: true,
},
});
const { vm } = wrapper;
vm.openPopup();
const btn = wrapper.find('.mx-datepicker-btn-confirm');
expect(btn.exists()).toBe(true);
// click the date expect popup don't close
vm.handleSelectDate(new Date(2018, 5, 5));
expect(wrapper.emitted().input).toBeUndefined();
expect(vm.popupVisible).toBe(true);
btn.trigger('click');
expect(wrapper.emitted().input[0][0]).toEqual(new Date(2018, 5, 5));
expect(vm.popupVisible).toBe(false);
});
it('prop: confirmText', () => {
wrapper = shallowMount(DatePicker, {
propsData: {
open: true,
confirm: true,
confirmText: 'test',
},
});
const btn = wrapper.find('.mx-datepicker-btn-confirm');
expect(btn.text()).toBe('test');
});
it('prop: appendToBody', () => {
wrapper = mount(DatePicker, {
propsData: {
open: true,
appendToBody: true,
},
});
const popup = wrapper.find('.mx-datepicker-popup');
expect(popup.element.parentNode).toBe(document.body);
});
});
+43
View File
@@ -0,0 +1,43 @@
import { mount } from '@vue/test-utils';
import DatetimePanel from '../src/datetime/datetime-panel';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('DatetimePanel', () => {
it('feat: click date', () => {
wrapper = mount(DatetimePanel, {
propsData: {
defaultValue: new Date(2019, 9, 1, 12),
},
});
const td = wrapper.find('.mx-table-date td:nth-child(4)');
td.trigger('click');
expect(wrapper.emitted().select[0][0]).toEqual(new Date(2019, 9, 2, 12));
let timeTitle = wrapper.find('.mx-time-header-title');
expect(timeTitle.exists()).toBe(true);
timeTitle.trigger('click');
timeTitle = wrapper.find('.mx-time-header-title');
expect(timeTitle.exists()).toBe(false);
});
it('feat: disabled time', () => {
const disabledDate = date => date < new Date(2019, 9, 2);
const disabledTime = date => date < new Date(2019, 9, 2, 12);
wrapper = mount(DatetimePanel, {
propsData: {
defaultValue: new Date(2019, 9, 1),
disabledDate,
disabledTime,
},
});
const td = wrapper.find('.mx-table-date td:nth-child(4)');
td.trigger('click');
expect(wrapper.emitted().select).toBeUndefined();
const timeTitle = wrapper.find('.mx-time-header-title');
expect(timeTitle.text()).toBe('2019-10-02');
});
});
+62
View File
@@ -0,0 +1,62 @@
import { mount } from '@vue/test-utils';
import flushPromises from 'flush-promises';
import DatetimeRange from '../src/datetime/datetime-range';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('DatetimeRange', () => {
it('feat: click dates', async () => {
wrapper = mount(DatetimeRange, {
sync: false,
propsData: {
value: [new Date(2019, 9, 4, 18), new Date(2019, 9, 6, 12)],
},
});
const td = wrapper.find('.mx-table-date td:nth-child(4)');
const td2 = wrapper.find('.mx-table-date td:nth-child(5)');
td.trigger('click');
td2.trigger('click');
await flushPromises();
expect(wrapper.emitted().select[0][0]).toEqual([
new Date(2019, 9, 2, 18),
new Date(2019, 9, 3, 12),
]);
let timeTitle = wrapper.find('.mx-time-header-title');
expect(timeTitle.exists()).toBe(true);
timeTitle.trigger('click');
await flushPromises();
timeTitle = wrapper.find('.mx-time-header-title');
expect(timeTitle.exists()).toBe(false);
td.trigger('click');
td.trigger('click');
await flushPromises();
expect(wrapper.emitted().select[1][0]).toEqual([
new Date(2019, 9, 2, 18),
new Date(2019, 9, 2, 18),
]);
});
it('feat: disabled time', async () => {
const disabledDate = date => date < new Date(2019, 9, 2);
const disabledTime = date => date < new Date(2019, 9, 2, 12);
wrapper = mount(DatetimeRange, {
sync: false,
propsData: {
defaultValue: new Date(2019, 9, 1),
disabledDate,
disabledTime,
},
});
const td = wrapper.find('.mx-table-date td:nth-child(4)');
td.trigger('click');
td.trigger('click');
await flushPromises();
expect(wrapper.emitted().select).toBeUndefined();
const timeTitle = wrapper.find('.mx-time-header-title');
expect(timeTitle.text()).toBe('2019-10-02');
});
});
+50
View File
@@ -0,0 +1,50 @@
import { mount } from '@vue/test-utils';
import DatePicker from '../src/date-picker.vue';
import '../src/locale/zh-cn';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('Locale', () => {
it('render the correct default locale', () => {
wrapper = mount(DatePicker, {
propsData: {
value: new Date(2019, 9, 10),
open: true,
},
});
expect(wrapper.find('.mx-table-date th').text()).toBe('一');
expect(wrapper.find('.mx-table-date td').element.title).toBe('2019-09-30');
});
it('prop: lang - string', () => {
wrapper = mount(DatePicker, {
propsData: {
value: new Date(2019, 9, 10),
open: true,
lang: 'en',
titleFormat: 'MMM DD, YYYY',
},
});
expect(wrapper.find('.mx-table-date th').text()).toBe('Su');
expect(wrapper.find('.mx-table-date td').element.title).toBe('Sep 29, 2019');
});
it('prop: lang - object', () => {
wrapper = mount(DatePicker, {
propsData: {
open: true,
lang: {
formatLocale: {
firstDayOfWeek: 2,
},
days: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
},
},
});
expect(wrapper.find('.mx-table-date th').text()).toBe('周二');
});
});
+22
View File
@@ -0,0 +1,22 @@
import { mount } from '@vue/test-utils';
import TableDate from '../src/calendar/table-date.vue';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('TableDate', () => {
it('corrent render', () => {
wrapper = mount(TableDate, {
propsData: {
calendarYear: 2019,
calendarMonth: 9,
firstDayOfWeek: 1,
titleFormat: 'DD/MM/YYYY',
},
});
expect(wrapper.element).toMatchSnapshot();
});
});
+24
View File
@@ -0,0 +1,24 @@
import { mount } from '@vue/test-utils';
import TableMonth from '../src/calendar/table-month.vue';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('TableMonth', () => {
it('correct render', () => {
wrapper = mount(TableMonth, {
propsData: {
getClasses: month => {
if (month === 9) {
return 'active';
}
return '';
},
},
});
expect(wrapper.element).toMatchSnapshot();
});
});
+19
View File
@@ -0,0 +1,19 @@
import { mount } from '@vue/test-utils';
import TableYear from '../src/calendar/table-year.vue';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('TableYear', () => {
it('decade=2010', () => {
wrapper = mount(TableYear, {
propsData: {
decade: 2010,
},
});
expect(wrapper.element).toMatchSnapshot();
});
});
+99
View File
@@ -0,0 +1,99 @@
import { mount } from '@vue/test-utils';
import TimePanel from '../src/time/time-panel';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('TimePanel', () => {
it('render: correct classes of the columns', () => {
wrapper = mount(TimePanel, {
propsData: {
value: new Date(2019, 9, 4, 12, 30, 30),
disabledTime: date => date.getHours() < 10,
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('render: correct columns by format', () => {
wrapper = mount(TimePanel, {
propsData: {
value: new Date(2019, 9, 4),
format: 'hh:mm a',
minuteStep: 30,
hourOptions: Array.from({ length: 10 }).map((_, i) => i + 8),
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('render: correct classes of the fixed time list', () => {
wrapper = mount(TimePanel, {
propsData: {
value: new Date(2019, 10, 9, 12, 30),
disabledTime: date => date.getHours() < 10,
timePickerOptions: {
start: '08:30',
step: '00:30',
end: '18:30',
},
format: 'HH:mm',
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('render: correct 12hours in the fixed time list', () => {
wrapper = mount(TimePanel, {
propsData: {
value: new Date(2019, 10, 9, 12, 30),
timePickerOptions: {
start: '08:30',
step: '00:30',
end: '18:30',
},
format: 'hh:mm A',
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('feat: emit select event when click', () => {
wrapper = mount(TimePanel, {
propsData: {
format: 'hh:mm:ss a',
defaultValue: new Date(2019, 9, 10, 2),
},
});
const hour = wrapper.find('[data-type=hour] li:nth-child(2)');
hour.trigger('click');
expect(wrapper.emitted().select[0][0]).toEqual(new Date(2019, 9, 10, 1));
wrapper.setProps({ value: new Date(2019, 9, 10, 1) });
const minute = wrapper.find('[data-type=minute] li:nth-child(2)');
minute.trigger('click');
expect(wrapper.emitted().select[1][0]).toEqual(new Date(2019, 9, 10, 1, 1));
wrapper.setProps({ value: new Date(2019, 9, 10, 1, 1) });
const second = wrapper.find('[data-type=second] li:nth-child(2)');
second.trigger('click');
expect(wrapper.emitted().select[2][0]).toEqual(new Date(2019, 9, 10, 1, 1, 1));
wrapper.setProps({ value: new Date(2019, 9, 10, 1, 1, 1) });
const pm = wrapper.find('[data-type=ampm] li:nth-child(2)');
pm.trigger('click');
expect(wrapper.emitted().select[3][0]).toEqual(new Date(2019, 9, 10, 13, 1, 1));
});
it('feat: disabledTime should not emit event', () => {
wrapper = mount(TimePanel, {
propsData: {
value: new Date(2019, 9, 4, 12, 30, 30),
disabledTime: date => date.getHours() < 10,
},
});
const hour = wrapper.find('[data-type=hour] li:nth-child(2)');
hour.trigger('click');
expect(wrapper.emitted().select).toBeUndefined();
});
});
+36
View File
@@ -0,0 +1,36 @@
import { mount } from '@vue/test-utils';
import TimeRange from '../src/time/time-range';
let wrapper;
afterEach(() => {
wrapper.destroy();
});
describe('TimeRange', () => {
it('render: correct classes of the columns', () => {
wrapper = mount(TimeRange, {
propsData: {
format: 'hh:mm a',
minuteStep: 30,
hourStep: 2,
value: [new Date(2019, 9, 4, 8, 30, 0), new Date(2019, 9, 4, 18, 30, 0)],
},
});
expect(wrapper.element).toMatchSnapshot();
});
it('feat: change the end time when start > end', () => {
wrapper = mount(TimeRange, {
propsData: {
value: [new Date(2019, 9, 4, 8, 30, 0), new Date(2019, 9, 4, 18, 30, 0)],
},
});
const hour = wrapper.find('[data-type=hour] li:nth-child(20)');
hour.trigger('click');
expect(wrapper.emitted().select[0][0]).toEqual([
new Date(2019, 9, 4, 19, 30, 0),
new Date(2019, 9, 4, 19, 30, 0),
]);
});
});