import { mount } from '@vue/test-utils';
import { ref, nextTick } from 'vue';
import DTimeSelect from '../src/time-select';
import { useNamespace } from '../../shared/hooks/use-namespace';
import { Form as DForm, FormItem as DFormItem } from '../../form';
jest.mock('../../locale/create', () => ({
createI18nTranslate: () => jest.fn(),
}));
const ns = useNamespace('select', true);
const baseClass = ns.b();
const dropdownCls = ns.e('dropdown');
const selectItemCls = ns.e('item');
const selectInputCls = ns.e('input');
const clearCls = ns.e('clear');
const notDotNs = useNamespace('select');
const selectSMCls = notDotNs.m('sm');
const selectLGCls = notDotNs.m('lg');
const selectDisabledCls = notDotNs.m('disabled');
const selectItemDisabledCls = selectItemCls + ' ' + 'disabled';
describe('TimeSelect', () => {
it('time-select render work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" step="01:00" start="01:00" end="23:00"></d-time-select>`,
setup() {
const modelValue = ref('01:00');
return {
modelValue,
};
},
});
const container = wrapper.find(baseClass);
const dropdown = wrapper.find(dropdownCls);
const input = wrapper.find<HTMLInputElement>(selectInputCls);
expect(container.exists()).toBeTruthy();
expect(dropdown.exists()).toBeFalsy();
await input.trigger('click');
await nextTick();
const listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(23);
expect(listItems[0].classList).toContain('active');
expect(input.element.value).toBe('01:00');
wrapper.unmount();
});
it('time-select size work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" size="sm"></d-time-select>`,
setup() {
const modelValue = ref('00:30');
return {
modelValue,
};
},
});
let container = wrapper.find(baseClass);
expect(container.classes()).toContain(selectSMCls);
await wrapper.setProps({
size: 'lg',
});
container = wrapper.find(baseClass);
expect(container.classes()).toContain(selectLGCls);
wrapper.unmount();
});
it('time-select props size priority', async () => {
const dFormSize = ref('lg');
const dTimeSelectSize = ref('sm');
const wrapper = mount({
components: { DTimeSelect, DForm, DFormItem },
template: `
<DForm :size="dFormSize">
<DFormItem>
<d-time-select :size="dTimeSelectSize"></d-time-select>
</DFormItem>
</DForm>`,
setup() {
return {
dFormSize,
dTimeSelectSize,
};
},
});
const container = wrapper.find(baseClass);
expect(container.classes()).toContain(selectSMCls);
dTimeSelectSize.value = '';
await nextTick();
expect(container.classes()).toContain(selectLGCls);
dFormSize.value = '';
await nextTick();
expect(container.classes()).not.toContain(selectSMCls);
expect(container.classes()).not.toContain(selectLGCls);
wrapper.unmount();
});
it('time-select disabled work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" disabled></d-time-select>`,
setup() {
const modelValue = ref('00:30');
return {
modelValue,
};
},
});
const container = wrapper.find(baseClass);
expect(container.classes()).toContain(selectDisabledCls);
const input = wrapper.find(selectInputCls);
expect(input.attributes()).toHaveProperty('disabled');
wrapper.unmount();
});
it('time-select clear work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" clearable></d-time-select>`,
setup() {
const modelValue = ref('00:30');
return {
modelValue,
};
},
});
const container = wrapper.find(baseClass);
const clearIcon = container.find(clearCls);
expect(clearIcon.exists()).toBeTruthy();
await clearIcon.trigger('click');
const input = wrapper.find<HTMLInputElement>(selectInputCls);
expect(input.element.value).toBe('');
wrapper.unmount();
});
it('time-select events work', async () => {
const onChange = jest.fn();
const onFocus = jest.fn();
const onBlur = jest.fn();
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" @change="onChange" @focus="onFocus" @blur="onBlur"></d-time-select>`,
setup() {
const modelValue = ref('00:30');
return {
modelValue,
onChange,
onFocus,
onBlur,
};
},
});
const input = wrapper.find(selectInputCls);
await input.trigger('focus');
expect(onFocus).toBeCalledTimes(1);
await input.trigger('blur');
expect(onBlur).toBeCalledTimes(1);
await input.trigger('click');
const listItems = document.querySelectorAll(selectItemCls);
await listItems[2].dispatchEvent(new Event('click'));
expect(onChange).toBeCalled();
wrapper.unmount();
});
it('time-select step work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" start="01:00" end="23:00"></d-time-select>`,
setup() {
const modelValue = ref('');
return {
modelValue,
};
},
});
const container = wrapper.find(baseClass);
const dropdown = wrapper.find(dropdownCls);
const input = wrapper.find<HTMLInputElement>(selectInputCls);
expect(container.exists()).toBeTruthy();
expect(dropdown.exists()).toBeFalsy();
await input.trigger('click');
await nextTick();
let listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe((23 - 1) * 2 + 1);
await wrapper.setProps({
step: '0:1',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe((23 - 1) * 60 + 1);
await wrapper.setProps({
step: '01:49',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(13);
await wrapper.setProps({
step: '23:49',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(1);
await wrapper.setProps({
step: '00:00',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe((23 - 1) * 2 + 1);
await wrapper.setProps({
step: '-1:0',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe((23 - 1) * 2 + 1);
await wrapper.setProps({
step: '-2:20',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe((23 - 1) * 2 + 1);
await wrapper.setProps({
step: '02:-1',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe((23 - 1) * 2 + 1);
await wrapper.setProps({
step: '1:0',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(23);
wrapper.unmount();
});
it('time-select start/end work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" step="00:10"></d-time-select>`,
setup() {
const modelValue = ref('');
return {
modelValue,
};
},
});
const container = wrapper.find(baseClass);
const dropdown = wrapper.find(dropdownCls);
const input = wrapper.find<HTMLInputElement>(selectInputCls);
expect(container.exists()).toBeTruthy();
expect(dropdown.exists()).toBeFalsy();
await input.trigger('click');
await nextTick();
let listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(24 * 6 + 1);
await wrapper.setProps({
end: '17:00',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(17 * 6 + 1);
await wrapper.setProps({
start: '17:00',
end: '18:00',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(6 + 1);
await wrapper.setProps({
start: '18:00',
end: '02:00',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(listItems.length).toBe(0);
wrapper.unmount();
});
it('time-select min-time/max-time work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" max-time="18:30"></d-time-select>`,
setup() {
const modelValue = ref('');
return {
modelValue,
};
},
});
const isAllDisabled = (listItems: NodeListOf<Element>, begin: number, end = listItems.length - 1) => {
return Array.from(listItems)
.slice(begin, end)
.every((x) => x.classList.contains('disabled'));
};
const isAllAvailable = (listItems: NodeListOf<Element>, begin: number, end = listItems.length - 1) => {
return Array.from(listItems)
.slice(begin, end)
.every((x) => !x.classList.contains('disabled'));
};
const container = wrapper.find(baseClass);
const dropdown = wrapper.find(dropdownCls);
const input = wrapper.find<HTMLInputElement>(selectInputCls);
expect(container.exists()).toBeTruthy();
expect(dropdown.exists()).toBeFalsy();
await input.trigger('click');
await nextTick();
let listItems = document.querySelectorAll(selectItemCls);
expect(container.find(selectItemDisabledCls).exists()).toBeTruthy;
expect(listItems.length).toBe(24 * 2 + 1);
expect(isAllAvailable(listItems, 0, 18 * 2 + 1)).toBeTruthy();
await listItems[18 * 2 + 1].dispatchEvent(new Event('click'));
listItems = document.querySelectorAll(selectItemCls);
expect(listItems[18 * 2 + 1].classList).toContain('active');
expect(input.element.value).toBe('18:30');
await listItems[19 * 2].dispatchEvent(new Event('click'));
listItems = document.querySelectorAll(selectItemCls);
expect(listItems[19 * 2].classList).not.toContain('active');
expect(input.element.value).not.toBe('19:00');
expect(isAllDisabled(listItems, 19 * 2)).toBeTruthy();
await wrapper.setProps({
'min-time': '03:00',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(container.find(selectItemDisabledCls).exists()).toBeTruthy;
expect(listItems.length).toBe(24 * 2 + 1);
expect(isAllDisabled(listItems, 0, 3 * 2 - 1)).toBeTruthy();
expect(listItems[3 * 2].classList).not.toContain('disabled');
await listItems[3 * 2].dispatchEvent(new Event('click'));
listItems = document.querySelectorAll(selectItemCls);
expect(listItems[3 * 2].classList).toContain('active');
expect(input.element.value).toBe('03:00');
expect(isAllAvailable(listItems, 3 * 2, 18 * 2 + 1)).toBeTruthy();
expect(isAllDisabled(listItems, 19 * 2)).toBeTruthy();
await wrapper.setProps({
'min-time': '09:30',
'max-time': '18:30',
start: '08:00',
end: '20:00',
});
await input.trigger('click');
await nextTick();
listItems = document.querySelectorAll(selectItemCls);
expect(container.find(selectItemDisabledCls).exists()).toBeTruthy;
expect(listItems.length).toBe(12 * 2 + 1);
expect(isAllDisabled(listItems, 0, 2)).toBeTruthy();
expect(isAllAvailable(listItems, 3, 2 * 10 + 1)).toBeTruthy();
expect(isAllDisabled(listItems, 2 * 11)).toBeTruthy();
wrapper.unmount();
});
it('time-select placeholder work', async () => {
const wrapper = mount({
components: { DTimeSelect },
template: `<d-time-select v-model="modelValue" placeholder="测试placeholder是否正常渲染"></d-time-select>`,
setup() {
const modelValue = ref('');
return {
modelValue,
};
},
});
const input = wrapper.find<HTMLInputElement>(selectInputCls);
expect(input.attributes().placeholder).toBe('测试placeholder是否正常渲染');
await wrapper.setProps({
placeholder: 'placeholder',
});
await nextTick();
expect(input.attributes().placeholder).toBe('placeholder');
});
});