diff --git a/src/field/test/__snapshots__/index.legacy.js.snap b/src/field/test/__snapshots__/index.legacy.js.snap deleted file mode 100644 index 2c46a57c9..000000000 --- a/src/field/test/__snapshots__/index.legacy.js.snap +++ /dev/null @@ -1,141 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`arrow-direction prop 1`] = ` -
-
-
-
- -
-`; - -exports[`clearable prop 1`] = ` -
-
-
-
-
-`; - -exports[`clearable prop 2`] = ` -
-
-
-
-
-
-`; - -exports[`colon prop 1`] = ` -
-
foo:
-
-
-
-
-`; - -exports[`label-class prop 1`] = ` -
-
Label
-
-
-
-
-`; - -exports[`label-width prop with unit 1`] = ` -
-
Label
-
-
-
-
-`; - -exports[`label-width prop without unit 1`] = ` -
-
Label
-
-
-
-
-`; - -exports[`name prop 1`] = ` -
-
-
-
-
-`; - -exports[`reach max word-limit 1`] = ` -
-
-
-
3/3
-
-
-`; - -exports[`reach max word-limit null 1`] = ` -
-
-
-
0/3
-
-
-`; - -exports[`reach max word-limit undefined 1`] = ` -
-
-
-
0/3
-
-
-`; - -exports[`render extra slot 1`] = ` -
-
-
-
Extra -
-`; - -exports[`render input slot 1`] = ` -
-
-
-
Custom Input
-
-
-
-`; - -exports[`render label slot 1`] = ` -
-
Custom Label
-
-
-
-
-`; - -exports[`render textarea 1`] = ` -
-
-
-
-
-`; - -exports[`size prop 1`] = ` -
-
-
-
-
-`; diff --git a/src/field/test/__snapshots__/index.spec.js.snap b/src/field/test/__snapshots__/index.spec.js.snap new file mode 100644 index 000000000..84d758815 --- /dev/null +++ b/src/field/test/__snapshots__/index.spec.js.snap @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render colon when using colon prop 1`] = ` +
+ + foo: + +
+`; + +exports[`should render extra slot correctly 1`] = ` +
+
+
+ +
+
+ Extra +
+`; + +exports[`should render input slot correctly 1`] = ` +
+ Custom Input +
+`; + +exports[`should render label slot correctly 1`] = ` +
+ Custom Label +
+`; + +exports[`should render word limit correctly 1`] = ` +
+
+
+ +
+
+ + 3 + + /3 +
+
+
+`; + +exports[`should render word limit correctly when modelValue is null 1`] = ` +
+
+
+ +
+
+ + 0 + + /3 +
+
+
+`; + +exports[`should render word limit correctly when modelValue is undefined 1`] = ` +
+
+
+ +
+
+ + 0 + + /3 +
+
+
+`; diff --git a/src/field/test/index.legacy.js b/src/field/test/index.legacy.js deleted file mode 100644 index 420398a9c..000000000 --- a/src/field/test/index.legacy.js +++ /dev/null @@ -1,436 +0,0 @@ -import Field from '..'; -import { mount, later } from '../../../test'; - -test('input event', () => { - const wrapper = mount(Field); - const input = wrapper.find('input'); - - input.element.value = '1'; - input.trigger('input'); - expect(wrapper.emitted('input')[0][0]).toEqual('1'); -}); - -test('click event', () => { - const wrapper = mount(Field); - - wrapper.trigger('click'); - expect(wrapper.emitted('click')[0][0]).toBeTruthy(); -}); - -test('click-input event', () => { - const wrapper = mount(Field); - - wrapper.find('input').trigger('click'); - expect(wrapper.emitted('click-input')[0][0]).toBeTruthy(); -}); - -test('click-input event when using input slot', () => { - const wrapper = mount(Field, { - slots: { - input: () => 'Custom Input', - }, - }); - - wrapper.find('.van-field__control').trigger('click'); - expect(wrapper.emitted('click-input')[0][0]).toBeTruthy(); -}); - -test('click-icon event', () => { - const wrapper = mount(Field, { - props: { - value: 'a', - leftIcon: 'contact', - rightIcon: 'search', - }, - }); - - wrapper.find('.van-field__left-icon').trigger('click'); - wrapper.find('.van-field__right-icon').trigger('click'); - expect(wrapper.emitted('click').length).toEqual(2); - expect(wrapper.emitted('click-left-icon')[0][0]).toBeTruthy(); - expect(wrapper.emitted('click-right-icon')[0][0]).toBeTruthy(); -}); - -test('number type', () => { - const wrapper = mount(Field, { - props: { - value: '', - type: 'number', - }, - }); - - const input = wrapper.find('input'); - - input.element.value = '1'; - input.trigger('input'); - expect(wrapper.emitted('input')[0][0]).toEqual('1'); - - input.element.value = '1.2.'; - input.trigger('input'); - expect(wrapper.emitted('input')[1][0]).toEqual('1.2'); - - input.element.value = '123abc'; - input.trigger('input'); - expect(wrapper.emitted('input')[2][0]).toEqual('123'); -}); - -test('digit type', () => { - const wrapper = mount(Field, { - props: { - value: '', - type: 'digit', - }, - }); - - const input = wrapper.find('input'); - - input.element.value = '1'; - input.trigger('input'); - expect(wrapper.emitted('input')[0][0]).toEqual('1'); - - input.element.value = '1.'; - input.trigger('input'); - expect(wrapper.emitted('input')[1][0]).toEqual('1'); - - input.element.value = '123abc'; - input.trigger('input'); - expect(wrapper.emitted('input')[2][0]).toEqual('123'); -}); - -test('render textarea', async () => { - const wrapper = mount(Field, { - props: { - type: 'textarea', - autosize: true, - }, - }); - - await later(); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('autosize textarea field', () => { - const wrapper = mount(Field, { - props: { - type: 'textarea', - autosize: {}, - }, - }); - - const value = '1'.repeat(20); - const textarea = wrapper.find('.van-field__control'); - - wrapper.setProps({ value }); - expect(textarea.element.value).toEqual(value); -}); - -test('autosize object', async () => { - const wrapper = mount(Field, { - props: { - type: 'textarea', - autosize: { - maxHeight: 100, - minHeight: 50, - }, - }, - }); - - const textarea = wrapper.find('.van-field__control'); - - await later(); - expect(textarea.element.style.height).toEqual('50px'); -}); - -test('blur method', () => { - const fn = jest.fn(); - const wrapper = mount(Field); - - wrapper.vm.$on('blur', fn); - wrapper.find('input').element.focus(); - wrapper.vm.blur(); - - expect(fn).toHaveBeenCalledTimes(1); -}); - -test('focus method', () => { - const fn = jest.fn(); - const wrapper = mount(Field); - - wrapper.vm.$on('focus', fn); - wrapper.vm.focus(); - - expect(fn).toHaveBeenCalledTimes(1); -}); - -test('maxlength', async () => { - const wrapper = mount(Field, { - attrs: { - maxlength: 3, - }, - props: { - value: 1234, - type: 'number', - }, - listeners: { - input(value) { - wrapper && wrapper.setProps({ value }); - }, - }, - }); - - const input = wrapper.find('input'); - expect(input.element.value).toEqual('123'); - - input.element.value = 1234; - input.trigger('input'); - expect(input.element.value).toEqual('123'); - expect(wrapper.emitted('input')[0][0]).toEqual('123'); - - // see: https://github.com/youzan/vant/issues/7265 - input.element.value = 1423; - input.trigger('input'); - expect(input.element.value).toEqual('123'); -}); - -test('clearable prop', () => { - const wrapper = mount(Field, { - props: { - value: 'test', - clearable: true, - }, - }); - - expect(wrapper.html()).toMatchSnapshot(); - const input = wrapper.find('input'); - input.trigger('focus'); - expect(wrapper.html()).toMatchSnapshot(); - - wrapper.find('.van-field__clear').trigger('touchstart'); - expect(wrapper.emitted('input')[0][0]).toEqual(''); - expect(wrapper.emitted('clear')[0][0]).toBeTruthy(); -}); - -test('clear-trigger prop', () => { - const wrapper = mount(Field, { - props: { - value: 'test', - clearable: true, - clearTrigger: 'always', - }, - }); - - expect(wrapper.contains('.van-field__clear')).toBeTruthy(); -}); - -test('render input slot', () => { - const wrapper = mount(Field, { - slots: { - input: () => 'Custom Input', - }, - }); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('render label slot', () => { - const wrapper = mount(Field, { - slots: { - label: () => 'Custom Label', - }, - }); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('render extra slot', () => { - const wrapper = mount(Field, { - slots: { - extra: () => 'Extra', - }, - }); - - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('size prop', () => { - const wrapper = mount(Field, { - props: { - size: 'large', - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('label-width prop with unit', () => { - const wrapper = mount(Field, { - props: { - label: 'Label', - labelWidth: '10rem', - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('label-width prop without unit', () => { - const wrapper = mount(Field, { - props: { - label: 'Label', - labelWidth: 100, - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('label-class prop', () => { - const wrapper = mount(Field, { - props: { - label: 'Label', - labelClass: 'custom-label-class', - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('arrow-direction prop', () => { - const wrapper = mount(Field, { - props: { - isLink: true, - arrowDirection: 'up', - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('formatter prop', () => { - const wrapper = mount(Field, { - props: { - value: 'abc123', - formatter: (value) => value.replace(/\d/g, ''), - }, - }); - - expect(wrapper.emitted('input')[0][0]).toEqual('abc'); - - const input = wrapper.find('input'); - input.element.value = '123efg'; - input.trigger('input'); - expect(wrapper.emitted('input')[1][0]).toEqual('efg'); -}); - -test('format-trigger prop', () => { - const wrapper = mount(Field, { - props: { - value: 'abc123', - formatTrigger: 'onBlur', - formatter: (value) => value.replace(/\d/g, ''), - }, - }); - - wrapper.vm.$on('input', (value) => { - wrapper.setProps({ value }); - }); - - expect(wrapper.emitted('input')[0][0]).toEqual('abc'); - - const input = wrapper.find('input'); - input.element.value = '123efg'; - input.trigger('input'); - expect(wrapper.emitted('input')[1][0]).toEqual('123efg'); - input.trigger('blur'); - expect(wrapper.emitted('input')[2][0]).toEqual('efg'); -}); - -test('reach max word-limit', () => { - const wrapper = mount(Field, { - props: { - value: 'foo', - maxlength: 3, - showWordLimit: true, - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('reach max word-limit undefined', () => { - const wrapper = mount(Field, { - props: { - value: undefined, - maxlength: 3, - showWordLimit: true, - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('reach max word-limit null', () => { - const wrapper = mount(Field, { - props: { - value: null, - maxlength: 3, - showWordLimit: true, - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('name prop', () => { - const wrapper = mount(Field, { - props: { - name: 'foo', - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('call focus method before mounted', (done) => { - mount(Field, { - created() { - this.focus(); - this.blur(); - done(); - }, - }); -}); - -test('destroy field', () => { - mount(Field).unmount(); -}); - -test('colon prop', () => { - const wrapper = mount(Field, { - props: { - label: 'foo', - colon: true, - }, - }); - expect(wrapper.html()).toMatchSnapshot(); -}); - -test('should blur search input on enter', () => { - const wrapper = mount(Field); - - wrapper.find('input').element.focus(); - wrapper.find('input').trigger('keypress.enter'); - expect(wrapper.emitted('blur')).toBeFalsy(); - - wrapper.setProps({ type: 'textarea' }); - wrapper.find('textarea').element.focus(); - wrapper.find('textarea').trigger('keypress.enter'); - expect(wrapper.emitted('blur')).toBeFalsy(); - - wrapper.setProps({ type: 'search' }); - wrapper.find('input').element.focus(); - wrapper.find('input').trigger('keypress.enter'); - expect(wrapper.emitted('blur')).toBeTruthy(); -}); - -test('value is null', () => { - const wrapper = mount(Field, { - props: { - value: null, - }, - }); - - expect(wrapper.find('input').element.value).toEqual(''); - expect(wrapper.emitted('input')[0][0]).toEqual(''); -}); diff --git a/src/field/test/index.spec.js b/src/field/test/index.spec.js new file mode 100644 index 000000000..181f0ccc4 --- /dev/null +++ b/src/field/test/index.spec.js @@ -0,0 +1,421 @@ +import Field from '..'; +import { mount } from '../../../test'; + +test('should emit "update:modelValue" event when after inputing', () => { + const wrapper = mount(Field); + const input = wrapper.find('input'); + + input.element.value = '1'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual('1'); +}); + +test('should emit click-input event when input is clicked', () => { + const wrapper = mount(Field); + wrapper.find('input').trigger('click'); + expect(wrapper.emitted('click-input')[0][0]).toBeTruthy(); +}); + +test('should evit click-input event when using input slot', () => { + const wrapper = mount(Field, { + slots: { + input: () => 'Custom Input', + }, + }); + + wrapper.find('.van-field__control').trigger('click'); + expect(wrapper.emitted('click-input')[0][0]).toBeTruthy(); +}); + +test('should emit click-left-icon event when left icon is clicked', () => { + const wrapper = mount(Field, { + props: { + leftIcon: 'contact', + }, + }); + + wrapper.find('.van-field__left-icon').trigger('click'); + expect(wrapper.emitted('click-left-icon')[0][0]).toBeTruthy(); +}); + +test('should emit click-right-icon event when right icon is clicked', () => { + const wrapper = mount(Field, { + props: { + rightIcon: 'search', + }, + }); + + wrapper.find('.van-field__right-icon').trigger('click'); + expect(wrapper.emitted('click-right-icon')[0][0]).toBeTruthy(); +}); + +test('should format input value when type is number', () => { + const wrapper = mount(Field, { + props: { + type: 'number', + modelValue: '', + }, + }); + + const input = wrapper.find('input'); + + input.element.value = '1'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual('1'); + + input.element.value = '1.2.'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[1][0]).toEqual('1.2'); + + input.element.value = '123abc'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[2][0]).toEqual('123'); +}); + +test('should format input value when type is digit', () => { + const wrapper = mount(Field, { + props: { + type: 'digit', + modelValue: '', + }, + }); + + const input = wrapper.find('input'); + + input.element.value = '1'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual('1'); + + input.element.value = '1.'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[1][0]).toEqual('1'); + + input.element.value = '123abc'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[2][0]).toEqual('123'); +}); + +// TODO +// test('should render textarea when type is textarea', async () => { +// const wrapper = mount(Field, { +// props: { +// type: 'textarea', +// autosize: true, +// }, +// }); + +// await later(); +// expect(wrapper.html()).toMatchSnapshot(); +// }); + +// test('autosize textarea field', () => { +// const wrapper = mount(Field, { +// props: { +// type: 'textarea', +// autosize: {}, +// }, +// }); + +// const value = '1'.repeat(20); +// const textarea = wrapper.find('.van-field__control'); + +// wrapper.setProps({ value }); +// expect(textarea.element.value).toEqual(value); +// }); + +// test('autosize object', async () => { +// const wrapper = mount(Field, { +// props: { +// type: 'textarea', +// autosize: { +// maxHeight: 100, +// minHeight: 50, +// }, +// }, +// }); + +// const textarea = wrapper.find('.van-field__control'); + +// await later(); +// expect(textarea.element.style.height).toEqual('50px'); +// }); + +test('should call input.focus when vm.focus is called', () => { + const wrapper = mount(Field); + const onFocus = jest.fn(); + wrapper.find('input').element.focus = onFocus; + + wrapper.vm.focus(); + expect(onFocus).toHaveBeenCalledTimes(1); +}); + +test('should call input.blur when vm.blur is called', () => { + const wrapper = mount(Field); + const onBlur = jest.fn(); + wrapper.find('input').element.blur = onBlur; + + wrapper.vm.blur(); + expect(onBlur).toHaveBeenCalledTimes(1); +}); + +test('should limit maxlength of input value when using maxlength prop', async () => { + const wrapper = mount(Field, { + props: { + type: 'number', + maxlength: 3, + modelValue: 1234, + }, + }); + + const input = wrapper.find('input'); + expect(input.element.value).toEqual('123'); + + input.element.value = 1234; + input.trigger('input'); + expect(input.element.value).toEqual('123'); + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual('123'); + await wrapper.setProps({ modelValue: '123' }); + + // see: https://github.com/youzan/vant/issues/7265 + input.element.value = 1423; + input.trigger('input'); + expect(input.element.value).toEqual('123'); +}); + +test('should render clear icon when using clearable prop', async () => { + const wrapper = mount(Field, { + props: { + clearable: true, + modelValue: 'test', + }, + }); + + expect(wrapper.find('.van-field__clear').exists()).toBeFalsy(); + const input = wrapper.find('input'); + await input.trigger('focus'); + expect(wrapper.find('.van-field__clear').exists()).toBeTruthy(); + + wrapper.find('.van-field__clear').trigger('touchstart'); + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual(''); + expect(wrapper.emitted('clear')[0][0]).toBeTruthy(); +}); + +test('should always render clear icon when clear-trigger prop is always', () => { + const wrapper = mount(Field, { + props: { + clearable: true, + modelValue: 'test', + clearTrigger: 'always', + }, + }); + + expect(wrapper.find('.van-field__clear').exists()).toBeTruthy(); +}); + +test('should render input slot correctly', () => { + const wrapper = mount(Field, { + slots: { + input: () => 'Custom Input', + }, + }); + + expect(wrapper.find('.van-field__control').html()).toMatchSnapshot(); +}); + +test('should render label slot correctly', () => { + const wrapper = mount(Field, { + slots: { + label: () => 'Custom Label', + }, + }); + + expect(wrapper.find('.van-field__label').html()).toMatchSnapshot(); +}); + +test('should render extra slot correctly', () => { + const wrapper = mount(Field, { + slots: { + extra: () => 'Extra', + }, + }); + + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('should change cell size when using size prop', () => { + const wrapper = mount(Field, { + props: { + size: 'large', + }, + }); + expect(wrapper.classes()).toContain('van-cell--large'); +}); + +test('should allow to set label width with unit', () => { + const wrapper = mount(Field, { + props: { + label: 'Label', + labelWidth: '10rem', + }, + }); + + const label = wrapper.find('.van-field__label').element; + expect(label.style.width).toEqual('10rem'); +}); + +test('should allow to set label width without unit', () => { + const wrapper = mount(Field, { + props: { + label: 'Label', + labelWidth: 100, + }, + }); + + const label = wrapper.find('.van-field__label').element; + expect(label.style.width).toEqual('100px'); +}); + +test('should render label class name when using label-class prop', () => { + const wrapper = mount(Field, { + props: { + label: 'Label', + labelClass: 'custom-class', + }, + }); + + expect(wrapper.find('.van-field__label').classes()).toContain('custom-class'); +}); + +test('should change arrow direction when using arrow-direction prop', () => { + const wrapper = mount(Field, { + props: { + isLink: true, + arrowDirection: 'up', + }, + }); + expect(wrapper.find('.van-icon-arrow-up').exists()).toBeTruthy(); +}); + +test('should allow to format value with formatter prop', () => { + const wrapper = mount(Field, { + props: { + modelValue: 'abc123', + formatter: (value) => value.replace(/\d/g, ''), + }, + }); + + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual('abc'); + + const input = wrapper.find('input'); + input.element.value = '123efg'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[1][0]).toEqual('efg'); +}); + +test('should trigger format after bluring when format-trigger prop is blur', async () => { + const wrapper = mount(Field, { + props: { + modelValue: 'abc123', + formatTrigger: 'onBlur', + formatter: (value) => value.replace(/\d/g, ''), + }, + }); + + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual('abc'); + await wrapper.setProps({ modelValue: 'abc' }); + + const input = wrapper.find('input'); + input.element.value = '123efg'; + input.trigger('input'); + expect(wrapper.emitted('update:modelValue')[1][0]).toEqual('123efg'); + await wrapper.setProps({ modelValue: '123efg' }); + + input.trigger('blur'); + expect(wrapper.emitted('update:modelValue')[2][0]).toEqual('efg'); +}); + +test('should render word limit correctly', () => { + const wrapper = mount(Field, { + props: { + modelValue: 'foo', + maxlength: 3, + showWordLimit: true, + }, + }); + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('should render word limit correctly when modelValue is undefined', () => { + const wrapper = mount(Field, { + props: { + modelValue: undefined, + maxlength: 3, + showWordLimit: true, + }, + }); + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('should render word limit correctly when modelValue is null', () => { + const wrapper = mount(Field, { + props: { + modelValue: undefined, + maxlength: 3, + showWordLimit: true, + }, + }); + expect(wrapper.html()).toMatchSnapshot(); +}); + +test('should render input name when using name prop', () => { + const wrapper = mount(Field, { + props: { + name: 'foo', + }, + }); + expect(wrapper.find('input').element.getAttribute('name')).toEqual('foo'); +}); + +test('should allow to destroy field', () => { + mount(Field).unmount(); +}); + +test('should render colon when using colon prop', () => { + const wrapper = mount(Field, { + props: { + label: 'foo', + colon: true, + }, + }); + expect(wrapper.find('.van-field__label').html()).toMatchSnapshot(); +}); + +// TODO +// test('should blur search input on enter', () => { +// const wrapper = mount(Field); + +// wrapper.find('input').element.focus(); +// wrapper.find('input').trigger('keypress.enter'); +// expect(wrapper.emitted('blur')).toBeFalsy(); + +// wrapper.setProps({ type: 'textarea' }); +// wrapper.find('textarea').element.focus(); +// wrapper.find('textarea').trigger('keypress.enter'); +// expect(wrapper.emitted('blur')).toBeFalsy(); + +// wrapper.setProps({ type: 'search' }); +// wrapper.find('input').element.focus(); +// wrapper.find('input').trigger('keypress.enter'); +// expect(wrapper.emitted('blur')).toBeTruthy(); +// }); + +test('should format value after mounted if initial modelValue is null', () => { + const wrapper = mount(Field, { + props: { + modelValue: null, + }, + }); + + expect(wrapper.find('input').element.value).toEqual(''); + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual(''); +});