1
0
mirror of synced 2024-11-25 14:56:03 +03:00
vue-formulario/test/unit/FormulateInputText.test.js

314 lines
13 KiB
JavaScript
Raw Normal View History

import Vue from 'vue'
import flushPromises from 'flush-promises'
import { mount } from '@vue/test-utils'
import Formulate from '../../src/Formulate.js'
2019-11-01 23:01:42 +03:00
import FormulateInput from '@/FormulateInput.vue'
import FormulateInputText from '@/inputs/FormulateInputText.vue'
import { doesNotReject } from 'assert';
Vue.use(Formulate)
/**
* Test each type of text element
*/
describe('FormulateInputText', () => {
it('renders text input when type is "text"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders search input when type is "search"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'search' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders email input when type is "email"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'email' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders number input when type is "number"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'number' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders color input when type is "color"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'color' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders date input when type is "date"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'date' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders month input when type is "month"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'month' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders password input when type is "password"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'password' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders tel input when type is "tel"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'tel' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders time input when type is "time"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'time' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders url input when type is "url"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'url' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
it('renders week input when type is "week"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'week' } })
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent(FormulateInputText).exists()).toBe(true)
})
/**
* Test rendering functionality to text inputs
*/
it('automatically assigns an id', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
expect(wrapper.vm.context).toHaveProperty('id')
expect(wrapper.find(`input[id="${wrapper.vm.context.attributes.id}"]`).exists()).toBe(true)
})
it('passes an explicitly given name prop through to the root text element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', name: 'foo' } })
expect(wrapper.find('input[name="foo"]').exists()).toBe(true)
})
it('passes an explicitly given name prop through to the root textarea element', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'textarea', name: 'foo' } })
expect(wrapper.find('textarea[name="foo"]').exists()).toBe(true)
})
it('additional context does not bleed through to text input attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } } )
expect(Object.keys(wrapper.find('input[type="text"]').attributes())).toEqual(["type", "id"])
})
it('additional context does not bleed through to textarea input attributes', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'textarea' } } )
expect(Object.keys(wrapper.find('textarea').attributes())).toEqual(["id"])
})
it('doesnt automatically add a label', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
expect(wrapper.find('label').exists()).toBe(false)
})
it('renders labels', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', label: 'Field label' } })
expect(wrapper.find(`label[for="${wrapper.vm.context.attributes.id}"]`).exists()).toBe(true)
})
it('doesnt automatically render help text', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
expect(wrapper.find(`.formulate-input-help`).exists()).toBe(false)
})
it('renders help text', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', help: 'This is some help text' } })
expect(wrapper.find(`.formulate-input-help`).exists()).toBe(true)
})
/**
* Test data binding
*/
it('emits input (vmodel) event with value when edited', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
wrapper.find('input').setValue('Updated Value')
expect(wrapper.emitted().input).toBeTruthy()
expect(wrapper.emitted().input[0]).toEqual(['Updated Value'])
})
it('doesnt re-context itself if there were no changes', async () => {
const wrapper = mount({
data () {
return {
valueA: 'first value',
valueB: 'second value'
}
},
template: `
<div>
<FormulateInput type="text" ref="first" v-model="valueA" :placeholder="valueA" />
<FormulateInput type="text" ref="second" v-model="valueB" :placeholder="valueB" />
</div>
`
})
await flushPromises()
2020-05-14 23:08:54 +03:00
const firstContext = wrapper.findComponent({ref: "first"}).vm.context
const secondContext = wrapper.findComponent({ref: "second"}).vm.context
wrapper.find('input').setValue('new value')
await flushPromises()
expect(firstContext).toBeTruthy()
expect(wrapper.vm.valueA === 'new value').toBe(true)
expect(wrapper.vm.valueB === 'second value').toBe(true)
2020-05-14 23:08:54 +03:00
expect(wrapper.findComponent({ref: "first"}).vm.context === firstContext).toBe(false)
expect(wrapper.findComponent({ref: "second"}).vm.context === secondContext).toBe(true)
})
2019-10-30 06:33:31 +03:00
it('uses the v-model value as the initial value', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', formulateValue: 'initial val' } })
expect(wrapper.find('input').element.value).toBe('initial val')
})
it('uses the value as the initial value', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', value: 'initial val' } })
expect(wrapper.find('input').element.value).toBe('initial val')
})
it('uses the value prop as the initial value when v-model provided', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', formulateValue: 'initial val', value: 'initial other val' } })
expect(wrapper.find('input').element.value).toBe('initial other val')
})
it('uses a proxy model internally if it doesnt have a v-model', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'textarea' } })
const input = wrapper.find('textarea')
input.setValue('changed value')
expect(wrapper.vm.proxy).toBe('changed value')
})
/**
* Test error handling
*/
it('doesnt automatically render errors', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
expect(wrapper.find('.formulate-input-errors').exists()).toBe(false)
})
it('accepts a single string as an error prop', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', error: 'This is an error' } })
expect(wrapper.find('.formulate-input-errors').exists()).toBe(true)
})
it('accepts an array as errors prop', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', errorBehavior: 'live', errors: ['This is an error', 'this is another'] } })
expect(wrapper.findAll('.formulate-input-error').length).toBe(2)
})
it('removes any duplicate errors', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', errorBehavior: 'live', errors: ['This is an error', 'This is an error'] } })
expect(wrapper.findAll('.formulate-input-error').length).toBe(1)
})
it('adds data-has-errors when there are errors', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', errorBehavior: 'live', errors: ['This is an error', 'This is an error'] } })
expect(wrapper.find('[data-has-errors]').exists()).toBe(true)
})
it('Should always show explicitly set errors, but not validation errors', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', validation: 'required', errorBehavior: 'blur', errors: ['Bad input'] } })
expect(wrapper.find('[data-has-errors]').exists()).toBe(true)
expect(wrapper.find('[data-is-showing-errors]').exists()).toBe(true)
expect(wrapper.findAll('.formulate-input-error').length).toBe(1)
})
it('Should show no errors when there are no errors', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text' } })
expect(wrapper.find('[data-has-errors]').exists()).toBe(false)
expect(wrapper.find('[data-is-showing-errors]').exists()).toBe(false)
expect(wrapper.findAll('.formulate-input-error').exists()).toBe(false)
})
it('allows error-behavior blur to be overridden with show-errors', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', errorBehavior: 'blur', showErrors: true, validation: 'required' } })
await flushPromises()
expect(wrapper.find('[data-has-errors]').exists()).toBe(true)
expect(wrapper.find('[data-is-showing-errors]').exists()).toBe(true)
expect(wrapper.findAll('.formulate-input-errors').exists()).toBe(true)
expect(wrapper.findAll('.formulate-input-error').length).toBe(1)
})
it('shows errors on blur with error-behavior blur', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'text', errorBehavior: 'blur', validation: 'required' } })
await wrapper.vm.$nextTick()
await flushPromises()
expect(wrapper.find('[data-has-errors]').exists()).toBe(true)
expect(wrapper.find('[data-is-showing-errors]').exists()).toBe(false)
expect(wrapper.findAll('.formulate-input-error').exists()).toBe(false)
expect(wrapper.vm.showValidationErrors).toBe(false)
wrapper.find('input').trigger('blur')
await flushPromises()
expect(wrapper.vm.showValidationErrors).toBe(true)
expect(wrapper.find('[data-is-showing-errors]').exists()).toBe(true)
// expect(wrapper.findAll('.formulate-input-errors').exists()).toBe(true)
// expect(wrapper.findAll('.formulate-input-error').length).toBe(1)
})
it('continues to show errors if validation fires more than one time', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'date', errorBehavior: 'live', validation: [['after', '01/01/2021']] , value: '01/01/1999' } })
await wrapper.vm.$nextTick()
await flushPromises()
expect(wrapper.find('[data-has-errors]').exists()).toBe(true)
wrapper.find('input').trigger('input')
await wrapper.vm.$nextTick()
await flushPromises()
expect(wrapper.find('[data-has-errors]').exists()).toBe(true)
})
it('allows label-before override with scoped slot', async () => {
const wrapper = mount(FormulateInput, {
propsData: { type: 'text', label: 'flavor' },
scopedSlots: {
label: '<label>{{ props.label }} town</label>'
}
})
expect(wrapper.find('label').text()).toBe('flavor town')
})
it('allows label-after override with scoped slot', async () => {
const wrapper = mount(FormulateInput, {
propsData: { type: 'text', label: 'flavor', labelPosition: 'after' },
scopedSlots: {
label: '<label>{{ props.label }} town</label>'
}
})
expect(wrapper.find('label').text()).toBe('flavor town')
})
2020-03-29 07:46:39 +03:00
it('allows help-before override', async () => {
const wrapper = mount(FormulateInput, {
propsData: { type: 'text', label: 'flavor', help: 'I love this next field...', helpPosition: 'before' },
})
expect(wrapper.find('label + *').classes('formulate-input-help')).toBe(true)
})
2020-03-29 07:46:39 +03:00
it('Allow help text override with scoped slot', async () => {
const wrapper = mount(FormulateInput, {
propsData: { type: 'text', name: 'soda', help: 'Do you want some'},
scopedSlots: {
help: '<small>{{ props.help }} {{ props.name }}?</small>'
}
})
expect(wrapper.find('small').text()).toBe('Do you want some soda?')
})
2020-04-16 16:22:58 +03:00
it('Allow errors override with scoped slot', async () => {
const wrapper = mount(FormulateInput, {
propsData: { type: 'text', name: 'soda', validation: 'required|in:foo,bar', errorBehavior: 'live' },
scopedSlots: {
errors: '<ul class="my-errors"><li v-for="error in props.visibleValidationErrors">{{ error }}</li></ul>'
}
})
await flushPromises();
expect(wrapper.findAll('.my-errors li').length).toBe(2)
})
})