vant/src/picker/test/index.spec.js
lllomh 59e08cb912
fix(Picker): Fix the issue when scrolling the mouse wheel once but the element scrolls multiple times (#12290)
* fix(Picker): Fix the problem of scrolling an element multiple times with one mouse roll

* fix(Test Cases): Corresponding Adjustment Test Cases about  #12290
2023-09-17 19:39:06 +08:00

411 lines
10 KiB
JavaScript

import Picker from '..';
import PickerColumn, {
MOMENTUM_LIMIT_TIME,
MOMENTUM_LIMIT_DISTANCE,
} from '../PickerColumn';
import { mount, triggerDrag, later } from '../../../test';
import { DEFAULT_ITEM_HEIGHT } from '../shared';
const simpleColumn = ['1990', '1991', '1992', '1993', '1994', '1995'];
const columns = [
{
values: ['vip', 'normal'],
className: 'column1',
},
{
values: simpleColumn,
className: 'column2',
},
];
test('simple columns confirm & cancel event', () => {
const wrapper = mount(Picker, {
propsData: {
showToolbar: true,
columns: simpleColumn,
},
});
wrapper.find('.van-picker__confirm').trigger('click');
wrapper.find('.van-picker__cancel').trigger('click');
expect(wrapper.emitted('confirm')[0]).toEqual(['1990', 0]);
expect(wrapper.emitted('cancel')[0]).toEqual(['1990', 0]);
wrapper.destroy();
});
test('multiple columns confirm & cancel event', () => {
const wrapper = mount(Picker, {
propsData: {
showToolbar: true,
columns,
},
});
wrapper.find('.van-picker__confirm').trigger('click');
wrapper.find('.van-picker__cancel').trigger('click');
const params = [
['vip', '1990'],
[0, 0],
];
expect(wrapper.emitted('confirm')[0]).toEqual(params);
expect(wrapper.emitted('cancel')[0]).toEqual(params);
});
test('set picker values', () => {
const wrapper = mount(Picker, {
propsData: {
columns,
},
});
const { vm } = wrapper;
expect(vm.getColumnValues(-1)).toEqual(undefined);
expect(vm.getColumnValues(1).length).toEqual(6);
expect(vm.getColumnValue(1)).toEqual('1990');
vm.setColumnValue(0, 'normal');
expect(vm.getColumnValue(0)).toEqual('normal');
vm.setColumnIndex(0, 0);
expect(vm.getColumnValue(0)).toEqual('vip');
vm.setColumnValue(1, '1991');
expect(vm.getColumnValue(1)).toEqual('1991');
vm.setColumnValues(0, ['vip', 'normal', 'other']);
expect(vm.getColumnValues(0).length).toEqual(3);
expect(vm.getValues().length).toEqual(2);
vm.setColumnValues(-1, []);
expect(vm.getValues().length).toEqual(2);
vm.setValues(['vip', '1992']);
expect(vm.getColumnIndex(1)).toEqual(2);
expect(vm.getColumnIndex(2)).toEqual(undefined);
expect(vm.getIndexes(2)).toEqual([0, 2]);
vm.setIndexes([1, 4]);
expect(vm.getColumnValue(1)).toEqual('1994');
expect(vm.getColumnValue(2)).toEqual(undefined);
});
test('drag columns', () => {
const wrapper = mount(Picker, {
propsData: {
columns,
},
});
triggerDrag(wrapper.find('.van-picker-column'), 0, -100);
wrapper.find('.van-picker-column ul').trigger('transitionend');
// 由于在极短的时间(大约几毫秒)移动 `100px`,因此再计算惯性滚动的距离时,
// 会得到一个很大的值,导致会滚动到且选中列表的最后一项
expect(wrapper.emitted('change')[0][1]).toEqual(['normal', '1990']);
});
test('drag simple columns', () => {
const wrapper = mount(Picker, {
propsData: {
columns: simpleColumn,
},
});
triggerDrag(wrapper.find('.van-picker-column'), 0, -100);
wrapper.find('.van-picker-column ul').trigger('transitionend');
// 由于在极短的时间(大约几毫秒)移动 `100px`,因此再计算惯性滚动的距离时,
// 会得到一个很大的值,导致会滚动到且选中列表的最后一项
expect(wrapper.emitted('change')[0][1]).toEqual('1995');
});
test('column watch default index', async () => {
const disabled = { disabled: true, text: 1 };
const wrapper = mount(PickerColumn, {
propsData: {
initialOptions: [disabled, ...simpleColumn],
valueKey: 'text',
itemHeight: 50,
visibleItemCount: 5,
},
});
await later();
expect(wrapper).toMatchSnapshot();
wrapper.vm.defaultIndex = 2;
expect(wrapper).toMatchSnapshot();
});
test('render title slot', () => {
const wrapper = mount({
template: `
<van-picker show-toolbar>
<template v-slot:title>Custom title</template>
</van-picker>
`,
});
expect(wrapper).toMatchSnapshot();
});
test('render confirm/cancel slot', () => {
const wrapper = mount({
template: `
<van-picker show-toolbar>
<template v-slot:confirm>Custom Confirm</template>
<template v-slot:cancel>Custom Cancel</template>
</van-picker>
`,
});
expect(wrapper).toMatchSnapshot();
});
test('render option slot with simple columns', () => {
const wrapper = mount({
template: `
<van-picker :columns="columns" show-toolbar>
<template #option="item">{{ item }}</template>
</van-picker>
`,
data() {
return { columns: ['foo', 'bar'] };
},
});
expect(wrapper).toMatchSnapshot();
});
test('render option slot with object columns', () => {
const wrapper = mount({
template: `
<van-picker :columns="columns" show-toolbar>
<template #option="item">{{ item.text }}</template>
</van-picker>
`,
data() {
return {
columns: [{ text: 'foo' }, { text: 'bar' }],
};
},
});
expect(wrapper).toMatchSnapshot();
});
test('simulation finger swipe again before transitionend', () => {
// mock getComputedStyle
// see: https://github.com/jsdom/jsdom/issues/2588
const originGetComputedStyle = window.getComputedStyle;
window.getComputedStyle = (ele) => {
const style = originGetComputedStyle(ele);
return {
...style,
transform: 'matrix(1, 0, 0, 1, 0, -5)',
};
};
const wrapper = mount(Picker, {
propsData: {
columns: simpleColumn,
},
});
triggerDrag(wrapper.find('.van-picker-column'), 0, -5);
triggerDrag(wrapper.find('.van-picker-column'), -5, -100);
wrapper.find('.van-picker-column ul').trigger('transitionend');
expect(wrapper.emitted('change')[0][1]).toEqual('1995');
});
test('click column item', () => {
const columns = [
{ text: '杭州' },
{ text: '宁波' },
{ text: '温州', disabled: true },
{ text: '嘉兴', disabled: true },
];
const wrapper = mount(Picker, {
propsData: {
columns,
},
});
wrapper.findAll('.van-picker-column__item').at(3).trigger('click');
expect(wrapper.emitted('change')[0][1]).toEqual(columns[1]);
});
test('toolbar-position prop', () => {
const wrapper = mount(Picker, {
propsData: {
showToolbar: true,
toolbarPosition: 'bottom',
},
});
expect(wrapper).toMatchSnapshot();
});
test('not allow html', () => {
const wrapper = mount(Picker, {
propsData: {
allowHtml: false,
columns: ['<div>option</div>'],
},
});
expect(wrapper).toMatchSnapshot();
});
test('columns-top、columns-bottom prop', () => {
const wrapper = mount(Picker, {
propsData: {
showToolbar: true,
},
scopedSlots: {
'columns-top': () => 'Custom Columns Top',
'columns-bottom': () => 'Custom Columns Bottom',
},
});
expect(wrapper).toMatchSnapshot();
});
test('watch columns change', () => {
const wrapper = mount(Picker, {
propsData: {
showToolbar: true,
columns: ['1', '2'],
defaultIndex: 1,
},
});
wrapper.setProps({
columns: ['2', '3'],
});
wrapper.find('.van-picker__confirm').trigger('click');
expect(wrapper.emitted('confirm')[0]).toEqual(['3', 1]);
});
test('should not reset index when columns unchanged', () => {
const wrapper = mount(Picker, {
propsData: {
showToolbar: true,
columns: ['1', '2'],
},
});
wrapper.vm.setIndexes([1]);
wrapper.setProps({
columns: ['1', '2'],
});
wrapper.find('.van-picker__confirm').trigger('click');
expect(wrapper.emitted('confirm')[0]).toEqual(['2', 1]);
});
test('set rem item-height', async () => {
const originGetComputedStyle = window.getComputedStyle;
window.getComputedStyle = () => ({ fontSize: '16px' });
const wrapper = mount(Picker, {
propsData: {
columns: simpleColumn.slice(0, 2),
itemHeight: '10rem',
},
});
await later();
expect(wrapper).toMatchSnapshot();
window.getComputedStyle = originGetComputedStyle;
});
test('readonly prop', () => {
const wrapper = mount(Picker, {
propsData: {
columns,
readonly: true,
},
});
triggerDrag(wrapper.find('.van-picker-column'), 0, -100);
wrapper.find('.van-picker-column ul').trigger('transitionend');
wrapper.findAll('.van-picker-column__item').at(3).trigger('click');
expect(wrapper.emitted('change')).toBeFalsy();
});
test('wheel event on columns is detected', async () => {
const onMouseWheel = jest.spyOn(PickerColumn.methods, 'onMouseWheel');
const wrapper = mount(PickerColumn, {
propsData: {
initialOptions: [...simpleColumn],
},
});
await wrapper.trigger('wheel');
expect(onMouseWheel).toHaveBeenCalled();
});
test('wheel scroll on columns', async () => {
const fakeScroll = (translateY, deltaY) => {
// mock getComputedStyle
// see: https://github.com/jsdom/jsdom/issues/2588
const originGetComputedStyle = window.getComputedStyle;
window.getComputedStyle = (ele) => {
const style = originGetComputedStyle(ele);
return {
...style,
transform: `matrix(1, 0, 0, 1, 0, ${translateY})`,
};
};
return new Promise((resolve) => {
const wrapper = mount(Picker, {
propsData: {
columns: simpleColumn,
},
});
wrapper.find('.van-picker-column').trigger('wheel', {
deltaY,
});
return later(MOMENTUM_LIMIT_TIME + 10)
.then(() => {
wrapper.find('.van-picker-column ul').trigger('transitionend');
resolve(wrapper.emitted('change'));
})
.finally(() => {
window.getComputedStyle = originGetComputedStyle;
});
});
};
const topToDown = await fakeScroll(110, -MOMENTUM_LIMIT_DISTANCE);
expect(topToDown).toEqual(undefined);
const topToUp = await fakeScroll(110, MOMENTUM_LIMIT_DISTANCE + 10);
expect(topToUp[0][1]).toEqual('1991');
const bottomToUp = await fakeScroll(-110, MOMENTUM_LIMIT_DISTANCE + 5);
expect(bottomToUp[0][1]).toEqual('1995');
const bottomToDown = await fakeScroll(-110, -(MOMENTUM_LIMIT_DISTANCE - 5));
expect(bottomToDown[0][1]).toEqual('1994');
const pos1992 = simpleColumn.indexOf('1992');
const momentum = await fakeScroll(
-110 + (pos1992 + 1) * DEFAULT_ITEM_HEIGHT,
MOMENTUM_LIMIT_DISTANCE + 10
);
expect(momentum[0][1]).toEqual(simpleColumn[pos1992 + 1]);
});