import { nextTick, ref } from 'vue' import { mount } from '@vue/test-utils' import { describe, expect, it, test } from 'vitest' import { ArrowDown, ArrowUp } from '@element-plus/icons-vue' import { ElFormItem } from '@element-plus/components/form' import InputNumber from '../src/input-number.vue' const mouseup = new Event('mouseup') const _mount = (options) => mount({ components: { 'el-input-number': InputNumber, 'el-form-item': ElFormItem, }, ...options, }) describe('InputNumber.vue', () => { test('create', async () => { const wrapper = _mount({ template: ` `, setup() { const num = ref(1) return { num, } }, }) expect(wrapper.find('input').exists()).toBe(true) }) test('modelValue', () => { const wrapper = _mount({ template: '', setup() { const inputText = ref(1) return { inputText, } }, }) expect(wrapper.find('input').element.value).toEqual('1') }) test('set modelValue undefined to form validate', async () => { const wrapper = _mount({ template: '

{{num}}

', setup() { const num = ref(undefined) return { num, } }, }) await nextTick() expect(wrapper.find('p').element.innerText).toBeUndefined() }) test('set modelValue undefined to display placeholder', async () => { const wrapper = _mount({ template: '', setup() { const inputText = ref(1) return { inputText, } }, }) expect(wrapper.find('input').element.value).toEqual('1') wrapper.vm.inputText = undefined await nextTick() expect(wrapper.find('input').element.value).toEqual('') expect(wrapper.find('input').element.getAttribute('aria-valuenow')).toEqual( 'null' ) }) test('min', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(1) return { num, } }, }) expect(wrapper.find('input').element.value).toEqual('3') wrapper.find('.el-input-number__decrease').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.find('input').element.value).toEqual('3') }) test('max', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(5) return { num, } }, }) expect(wrapper.find('input').element.value).toEqual('3') wrapper.find('.el-input-number__increase').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.find('input').element.value).toEqual('3') }) test('step, increase and decrease', async () => { document.body.innerHTML = '
' const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) wrapper.find('.el-input-number__decrease').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.find('input').element.value).toEqual('-2') wrapper.find('.el-input-number__increase').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.find('input').element.value).toEqual('0') wrapper.find('.el-input-number__increase').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.find('input').element.value).toEqual('2') }) test('step-strictly', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) await wrapper.find('input').setValue(3) expect(wrapper.find('input').element.value).toEqual('4') }) describe('precision accuracy 2', () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) it.each([ [1.1111111111, '1.11'], [17.275, '17.28'], [17.2745, '17.27'], [1.09, '1.09'], [1.009, '1.01'], [10.999, '11.00'], [15, '15.00'], [15.5, '15.50'], [15.555, '15.56'], ])( 'each precision accuracy test: $input $output', async (input, output) => { await wrapper.find('input').setValue(input) expect(wrapper.find('input').element.value).toEqual(`${output}`) } ) }) describe('precision accuracy 3', () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) it.each([ [1.1111111111, '1.111'], [17.275, '17.275'], [17.2745, '17.275'], [1.09, '1.090'], [10.999, '10.999'], [10.9999, '11.000'], [15.555, '15.555'], [1.3335, '1.334'], ])( 'each precision accuracy test: $input $output', async (input, output) => { await wrapper.find('input').setValue(input) expect(wrapper.find('input').element.value).toEqual(`${output}`) } ) }) test('disabled', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) wrapper.find('.el-input-number__decrease').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.find('input').element.value).toEqual('0') wrapper.find('.el-input-number__increase').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.find('input').element.value).toEqual('0') }) test('controls', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) expect(wrapper.find('.el-input-number__increase').exists()).toBe(false) expect(wrapper.find('.el-input-number__decrease').exists()).toBe(false) }) test('controls-position', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) expect(wrapper.findComponent(ArrowDown).exists()).toBe(true) expect(wrapper.findComponent(ArrowUp).exists()).toBe(true) }) test('change-event', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) wrapper.find('.el-input-number__increase').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.getComponent(InputNumber).emitted('change')).toHaveLength(1) expect(wrapper.getComponent(InputNumber).emitted().change[0]).toEqual([ 1, 0, ]) expect(wrapper.getComponent(InputNumber).emitted('input')).toHaveLength(1) expect( wrapper.getComponent(InputNumber).emitted('update:modelValue') ).toHaveLength(1) wrapper.find('.el-input-number__increase').trigger('mousedown') document.dispatchEvent(mouseup) await nextTick() expect(wrapper.getComponent(InputNumber).emitted('change')).toHaveLength(2) expect(wrapper.getComponent(InputNumber).emitted().change[1]).toEqual([ 2, 1, ]) expect(wrapper.getComponent(InputNumber).emitted('input')).toHaveLength(2) expect( wrapper.getComponent(InputNumber).emitted('update:modelValue') ).toHaveLength(2) }) test('blur-event', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) await wrapper.find('input').trigger('blur') expect(wrapper.getComponent(InputNumber).emitted('blur')).toHaveLength(1) }) test('focus-event', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(0) return { num, } }, }) await wrapper.find('input').trigger('focus') expect(wrapper.getComponent(InputNumber).emitted('focus')).toHaveLength(1) }) test('clear with :value-on-clear="null"', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(2) return { num, } }, }) const elInput = wrapper.findComponent({ name: 'ElInputNumber' }).vm elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(null) elInput.increase() await nextTick() expect(wrapper.vm.num).toBe(1) elInput.increase() await nextTick() expect(wrapper.vm.num).toBe(2) elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(null) elInput.decrease() await nextTick() expect(wrapper.vm.num).toBe(1) elInput.decrease() await nextTick() expect(wrapper.vm.num).toBe(1) }) test('clear with value-on-clear="min"', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(2) return { num, } }, }) const elInput = wrapper.findComponent({ name: 'ElInputNumber' }).vm elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(1) elInput.increase() await nextTick() expect(wrapper.vm.num).toBe(2) elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(1) elInput.decrease() await nextTick() expect(wrapper.vm.num).toBe(1) }) test('clear with value-on-clear="max"', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(2) return { num, } }, }) const elInput = wrapper.findComponent({ name: 'ElInputNumber' }).vm elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(10) elInput.increase() await nextTick() expect(wrapper.vm.num).toBe(10) elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(10) elInput.decrease() await nextTick() expect(wrapper.vm.num).toBe(9) }) test('clear with :value-on-clear="5"', async () => { const wrapper = _mount({ template: '', setup() { const num = ref(2) return { num, } }, }) const elInput = wrapper.findComponent({ name: 'ElInputNumber' }).vm elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(5) elInput.increase() await nextTick() expect(wrapper.vm.num).toBe(6) elInput.handleInputChange('') await nextTick() expect(wrapper.vm.num).toBe(5) elInput.decrease() await nextTick() expect(wrapper.vm.num).toBe(4) }) test('check increase and decrease button when modelValue not in [min, max]', async () => { const wrapper = _mount({ template: ` `, setup() { const num1 = ref(-5) const num2 = ref(15) const inputNumber1 = ref(null) const inputNumber2 = ref(null) return { num1, num2, inputNumber1, inputNumber2, } }, }) const elInputNumber1 = wrapper.vm.inputNumber1 const elInputNumber2 = wrapper.vm.inputNumber2 expect(wrapper.vm.num1).toBe(1) expect(wrapper.vm.num2).toBe(10) elInputNumber1.decrease() await nextTick() expect(wrapper.vm.num1).toBe(1) elInputNumber1.increase() await nextTick() expect(wrapper.vm.num1).toBe(2) elInputNumber1.increase() await nextTick() expect(wrapper.vm.num1).toBe(3) elInputNumber2.increase() await nextTick() expect(wrapper.vm.num2).toBe(10) elInputNumber2.decrease() await nextTick() expect(wrapper.vm.num2).toBe(9) elInputNumber2.decrease() await nextTick() expect(wrapper.vm.num2).toBe(8) }) describe('form item accessibility integration', () => { test('automatic id attachment', async () => { const wrapper = _mount({ template: ` `, }) await nextTick() const formItem = wrapper.find('[data-test-ref="item"]') const formItemLabel = formItem.find('.el-form-item__label') const innerInput = wrapper.find('.el-input__inner') expect(formItem.attributes().role).toBeFalsy() expect(formItemLabel.attributes().for).toBe(innerInput.attributes().id) }) test('specified id attachment', async () => { const wrapper = _mount({ template: ` `, }) await nextTick() const formItem = wrapper.find('[data-test-ref="item"]') const formItemLabel = formItem.find('.el-form-item__label') const innerInput = wrapper.find('.el-input__inner') expect(formItem.attributes().role).toBeFalsy() expect(innerInput.attributes().id).toBe('foobar') expect(formItemLabel.attributes().for).toBe(innerInput.attributes().id) }) test('form item role is group when multiple inputs', async () => { const wrapper = _mount({ template: ` `, }) await nextTick() const formItem = wrapper.find('[data-test-ref="item"]') expect(formItem.attributes().role).toBe('group') }) }) })