Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(DateTimePicker): add unit test for date-time-picker #407

Merged
merged 1 commit into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
880 changes: 785 additions & 95 deletions src/date-time-picker/__test__/__snapshots__/demo.test.jsx.snap

Large diffs are not rendered by default.

418 changes: 418 additions & 0 deletions src/date-time-picker/__test__/__snapshots__/index.test.jsx.snap

Large diffs are not rendered by default.

228 changes: 228 additions & 0 deletions src/date-time-picker/__test__/index.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
import { nextTick, ref } from 'vue';
import { mount } from '@vue/test-utils';
import { describe, it, expect, vi } from 'vitest';
import DateTimePicker from '../date-time-picker.vue';
import PickerItem from '../../picker/picker-item.vue';
import { DEFAULT_ITEM_HEIGHT, ANIMATION_TIME_LIMIT } from '../../picker/picker.class';

const makeTouch = (el, eventName, touchPosition) => {
const event = new Event(eventName);
if (touchPosition) {
event.changedTouches = [touchPosition];
}

el.dispatchEvent(event);
};

const simulateMoveOption = async (optionContainerEl, distance) => {
makeTouch(optionContainerEl, 'touchstart', { pageY: 0 });
makeTouch(optionContainerEl, 'touchmove', { pageY: -distance * DEFAULT_ITEM_HEIGHT });

vi.useFakeTimers().advanceTimersByTime(ANIMATION_TIME_LIMIT + 1);
makeTouch(optionContainerEl, 'touchend', { pageY: -distance * DEFAULT_ITEM_HEIGHT });
vi.useRealTimers();

await nextTick();
}

const prefix = 't'
const name = `${prefix}-date-time-picker`;

const renderLabel = (type, value) => {
if (type === 'year') {
return `${value}年`;
}
if (type === 'month') {
return `${value}月`;
}
if (type === 'date') {
return `${value}日`;
}
return value;
};

const addZero = (el) => {
return el < 10 ? `0${el}` : el
}

// 获取当前月份的天数
const getDateCount = (Y, M) => {
var d = new Date(Y, M, 0);
return d.getDate();
}

// 相关日期计算
const precisionRankRecord = ['year', 'month', 'date', 'hour', 'minute','second'];
const currentDate = new Date('2022-10-13');
const Y = currentDate.getFullYear();
const M = currentDate.getMonth() + 1;
const D = currentDate.getDate();
const defaultDateTime = `${Y}-${addZero(M)}-${addZero(D)}`;

const ret = [];
const generateColumn = (start, end, type) => {
const arr = [];
for (let i = start; i <= end; i++) {
const value = i.toString();
arr.push({
label: renderLabel ? renderLabel(type, i) : value,
value: type === 'month' ? `${+value - 1}` : value,
});
}
ret.push(arr);
};

describe('DateTimePicker', () => {
describe('props', () => {
it(': title && confirmBtn && cancelBtn', async () => {
const title = '';
const confirmBtn = '';
const cancelBtn = '';
const wrapper = mount(DateTimePicker, {
props: {
title,
confirmBtn,
cancelBtn
}
})
const $title = wrapper.find(`.${prefix}-picker__title`);
const $confirmButton = wrapper.find(`.${prefix}-picker__confirm`);
const $cancelButton = wrapper.find(`.${prefix}-picker__cancel`);
expect($title.text()).toBe(title || '选择时间');
expect($confirmButton.text()).toBe(confirmBtn || '确定');
expect($cancelButton.text()).toBe(cancelBtn || '取消');

const newTitle = '标题测试';
const newConfirmBtn = 'confirm';
const newCancelBtn = 'cancel';
await wrapper.setProps({
title: newTitle,
confirmBtn: newConfirmBtn,
cancelBtn: newCancelBtn
})
expect($title.text()).toBe(newTitle || '选择时间');
expect($confirmButton.text()).toBe(newConfirmBtn || '确定');
expect($cancelButton.text()).toBe(newCancelBtn || '取消');
});

it(': mode', async () => {
const defaultValue = defaultDateTime;
const modeArray = ['date', 'second'];
const wrapper = mount(DateTimePicker, {
props: {
defaultValue,
title: 'mode 测试',
mode: modeArray,
}
})
// mode = ['date', 'second'], 渲染年月日时分秒,6列
const pickerItem = wrapper.findComponent(PickerItem);
expect(pickerItem.exists()).toBeTruthy();
const $pickerItems = wrapper.findAllComponents(PickerItem);
expect($pickerItems).toHaveLength(6);
await wrapper.setProps({
mode: false
})
// mode = false, 不渲染列
expect(pickerItem.exists()).toBeFalsy();
});

it(': start && end ', async () => {
const defaultValue = defaultDateTime;
const start = "2020-6-30";
const end = "2025-6-30";

const startYear = start.split('-')[0];
const endYear =end.split('-')[0];

const wrapper = mount(DateTimePicker, {
props: {
defaultValue,
start,
end,
}
})
const $pickerItems = wrapper.findAllComponents(PickerItem);
let res = {};
$pickerItems.forEach((item, index) => {
res[precisionRankRecord[index]] = item.findAll(`.${prefix}-picker-item__item`)
});
expect(res[precisionRankRecord[0]].length).toEqual(endYear - startYear + 1);
});

it(': renderLabel', async () => {
generateColumn(Y - 10, Y + 10, 'year')
generateColumn(1, 12, 'month')
generateColumn(1, getDateCount(Y, M), 'date')

const defaultValue = defaultDateTime;
const wrapper = mount(DateTimePicker, {
props: {
defaultValue,
title: '自定义label',
renderLabel,
}
})
// mode = 'date', 渲染年月日,3列
const $pickerItems = wrapper.findAllComponents(PickerItem);
expect($pickerItems.length).toEqual(3);

let res = {};
$pickerItems.forEach((item, index) => {
res[precisionRankRecord[index]] = item.findAll(`.${prefix}-picker-item__item`)
});

Object.keys(res).forEach((key, keyIndex) => {
expect(res[key].length).toEqual(ret[keyIndex].length)
res[key].forEach((item, itemIndex) => {
expect(item.text()).toEqual(ret[keyIndex][itemIndex].label)
})
})
})
it(': onCancel', async () => {
const onCancel = vi.fn();
const wrapper = mount(DateTimePicker, {
props: {
onCancel,
}
})
const $cancelButton = wrapper.find(`.${prefix}-picker__cancel`);
await $cancelButton.trigger('click');
expect(onCancel).toBeCalledTimes(1);
})

it(': onPick', async () => {
const initValue = ref(defaultDateTime);
const onConfirm = vi.fn((e) => {
// confirm && change && pick 事件的返回值格式是 yyyy-mm-dd hh:mm:ss, 需要自行处理。
// Q: 返回值是否应该按照 mode 类型返回?
initValue.value = String(e).split(' ')[0].trim();
});
const onChange = vi.fn();
const onPick = vi.fn();
const wrapper = mount(DateTimePicker, {
props: {
value: initValue.value,
onConfirm,
onChange,
onPick
}
})
const $confirmButton = wrapper.find(`.${prefix}-picker__confirm`);
await $confirmButton.trigger('click');
expect(onConfirm).toBeCalledTimes(1);
expect(onChange).toBeCalledTimes(0); // value 不变,不触发 change
expect(onPick).toBeCalledTimes(0);
const el = wrapper.findAll(`.${prefix}-picker-item`);
const touchItemIndex = 0;
const touchIndex = 2;
simulateMoveOption(el[touchItemIndex].element, touchIndex);
expect(wrapper.element).toMatchSnapshot();
expect(onPick).toBeCalledTimes(1);
await $confirmButton.trigger('click');
expect(onConfirm).toBeCalledTimes(2);
expect(onChange).toBeCalledTimes(1);
expect(initValue.value).toEqual(`${ret[touchItemIndex][10 + touchIndex].value}-${addZero(M)}-${addZero(D)}`)
})
});
})
2 changes: 2 additions & 0 deletions src/date-time-picker/date-time-picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
ref="pickeInstance"
:value="currentPicker"
:title="title"
:confirm-btn="confirmButtonText"
:cancel-btn="cancelButtonText"
:columns="(selected) => generateDatePickerColumns(selected, start, end, renderLabel)"
@change="onChange"
@confirm="onConfirm"
Expand Down
8 changes: 4 additions & 4 deletions src/date-time-picker/demos/base.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<t-cell title="选择日期(年月日)" :note="pickerValue || '年 月 日'" @click="visible = true" />
<t-cell title="选择日期(年月日)" :note="pickerValueText || '年 月 日'" @click="visible = true" />
<t-popup v-model="visible" placement="bottom">
<t-date-time-picker
:value="pickerValue"
Expand All @@ -15,11 +15,10 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { cell } from 'tdesign-mobile-vue';

const visible = ref(false);
const pickerValue = ref('');

const pickerValue = ref('2021-12-23');
const pickerValueText = ref('');
const onChange = (value: string) => {
console.log('change: ', value);
};
Expand All @@ -36,6 +35,7 @@ const onCancel = () => {
const onConfirm = (value: string) => {
console.log('confirm: ', value);
pickerValue.value = value;
pickerValueText.value = value;
visible.value = false;
};
</script>
8 changes: 4 additions & 4 deletions src/date-time-picker/demos/custom-range.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<t-cell title="选择日期" :note="pickerValue || '年 月 日'" @click="visible = true" />
<t-cell title="选择日期" :note="pickerValueText || '年 月 日'" @click="visible = true" />
<t-popup v-model="visible" placement="bottom">
<t-date-time-picker
:value="pickerValue"
Expand All @@ -17,11 +17,10 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { cell } from 'tdesign-mobile-vue';

const visible = ref(false);
const pickerValue = ref('');

const pickerValue = ref('2021-12-23');
const pickerValueText = ref('');
const onChange = (value: string) => {
console.log('change: ', value);
};
Expand All @@ -38,6 +37,7 @@ const onCancel = () => {
const onConfirm = (value: string) => {
console.log('confirm: ', value);
pickerValue.value = value;
pickerValueText.value = value;
visible.value = false;
};
</script>
1 change: 0 additions & 1 deletion src/date-time-picker/demos/full.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import { cell } from 'tdesign-mobile-vue';
import { DateValue } from '../type';

const show = reactive({
Expand Down
60 changes: 0 additions & 60 deletions src/date-time-picker/demos/mobile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,68 +13,8 @@
</div>
</template>
<script lang="ts" setup>
import { computed, reactive, ref } from 'vue';
import dayjs from 'dayjs';
import { DateValue } from '../type';
import baseVue from './base.vue';
import yearMonthVue from './year-month.vue';
import timeVue from './time.vue';
import customRangeVue from './custom-range.vue';

const modeArray = ['date', 'second'];

const mode = ref(modeArray);
const show = reactive({
ymdhms: false,
ymd: false,
ym: false,
hm: false,

ymdhms2: false,
ymdhms3: false,
});
const text = reactive({
ymdhms: '2020-08-10 12:50:00',
ymd: '2020-08-10',
ym: '2020-08',
hm: '2020-08-10 12:01',

ymdhms2: '2020-08-10 12:50:00',
ymdhms3: '2020-08-10 12:50:00',
});

const showHm = computed(() => {
return dayjs(text.hm).format('HH:mm');
});

const onChange = (value: DateValue) => {
console.log('date-time-picker:change', value);
};

const onPick = (value: DateValue) => {
console.log('date-time-picker:pick', value);
};

const onCancel = () => {
console.log('date-time-picker:cancel');
Object.keys(show).forEach((item) => (show[item] = false));
};

const onConfirm = (value: DateValue) => {
console.log('date-time-picker:confirm', value);
Object.keys(show).forEach((item) => (show[item] = false));
};

const renderLabel = (type: string, value: number) => {
if (type === 'year') {
return `${value}年`;
}
if (type === 'month') {
return `${value}月`;
}
if (type === 'date') {
return `${value}日`;
}
return value;
};
</script>
1 change: 0 additions & 1 deletion src/date-time-picker/demos/time.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { cell } from 'tdesign-mobile-vue';

const visible = ref(false);
const pickerValue = ref('');
Expand Down
Loading