1
0
mirror of synced 2025-02-16 20:53:13 +03:00

Fixes #60 and merges #61.

- Bugfix: Fixes #60, a bug that caused an evaluation loop when selects or box types used an empty array as the options prop. Adds supporting test cases.
- Merges in #61 which passes the form name to the error handler function. Adds supporting test cases.
This commit is contained in:
Justin Schroeder 2020-04-13 11:59:54 -04:00 committed by GitHub
parent 07cf10342f
commit ada48ec31f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 99 additions and 9 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "@braid/vue-formulate",
"version": "2.2.6",
"version": "2.2.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "@braid/vue-formulate",
"version": "2.2.6",
"version": "2.2.7",
"description": "The easiest way to build forms in Vue.",
"main": "dist/formulate.umd.js",
"module": "dist/formulate.esm.js",

View File

@ -231,7 +231,7 @@ class Formulate {
* @param {error}
*/
handle (err, formName, skip = false) {
const e = skip ? err : this.options.errorHandler(err)
const e = skip ? err : this.options.errorHandler(err, formName)
if (formName && this.registry.has(formName)) {
this.registry.get(formName).applyErrors({
formErrors: arrayify(e.formErrors),

View File

@ -177,8 +177,6 @@ function createOptionList (options) {
optionList.push({ value, label: options[value], id: `${that.elementAttributes.id}_${value}` })
}
return optionList
} else if (Array.isArray(options) && !options.length) {
return [{ value: this.value, label: (this.label || this.name), id: this.context.id || nanoid(9) }]
}
return options
}

View File

@ -230,6 +230,47 @@ describe('FormulateForm', () => {
expect(wrapper.vm.$formulate.registry.get('login')).toBe(wrapper.vm)
})
it('calls custom error handler with error and name', async () => {
const mockHandler = jest.fn((err, name) => err);
const wrapper = mount({
template: `
<div>
<FormulateForm
name="login"
/>
<FormulateForm
name="register"
/>
</div>
`
})
wrapper.vm.$formulate.extend({ errorHandler: mockHandler })
wrapper.vm.$formulate.handle({ formErrors: ['This is an error message'] }, 'login')
expect(mockHandler.mock.calls.length).toBe(1);
expect(mockHandler.mock.calls[0]).toEqual([{ formErrors: ['This is an error message'] }, 'login']);
})
it('errors are displayed on correctly named components', async () => {
const wrapper = mount({
template: `
<div>
<FormulateForm
name="login"
/>
<FormulateForm
name="register"
/>
</div>
`
})
expect(wrapper.vm.$formulate.registry.has('login') && wrapper.vm.$formulate.registry.has('register')).toBe(true)
wrapper.vm.$formulate.handle({ formErrors: ['This is an error message'] }, 'login')
await flushPromises()
expect(wrapper.findAll('.formulate-form').length).toBe(2)
expect(wrapper.find('.formulate-form--login .formulate-form-errors').exists()).toBe(true)
expect(wrapper.find('.formulate-form--register .formulate-form-errors').exists()).toBe(false)
})
it('errors are displayed on correctly named components', async () => {
const wrapper = mount({
template: `

View File

@ -201,4 +201,10 @@ describe('FormulateInputBox', () => {
await flushPromises()
expect(wrapper.find('.formulate-input-error').exists()).toBe(true)
})
it('renders no boxes when options array is empty', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', options: [] } })
expect(wrapper.contains(FormulateInputGroup)).toBe(true)
expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false)
})
})

View File

@ -1,6 +1,6 @@
import Vue from 'vue'
import { mount } from '@vue/test-utils'
import Formulate from '../../src/Formulate.js'
import Formulate from '@/Formulate.js'
import FormulateInput from '@/FormulateInput.vue'
import FormulateInputButton from '@/inputs/FormulateInputButton.vue'

View File

@ -0,0 +1,45 @@
import Vue from 'vue'
import { mount } from '@vue/test-utils'
import flushPromises from 'flush-promises'
import Formulate from '@/Formulate.js'
import FormulateInput from '@/FormulateInput.vue'
import FormulateInputSelect from '@/inputs/FormulateInputSelect.vue'
Vue.use(Formulate)
describe('FormulateInputSelect', () => {
it('renders select input when type is "select"', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select' } })
expect(wrapper.contains(FormulateInputSelect)).toBe(true)
})
it('renders select options when options object is passed', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select', options: { first: 'First', second: 'Second' } } })
const option = wrapper.find('option[value="second"]')
expect(option.exists()).toBe(true)
expect(option.text()).toBe('Second')
})
it('renders select options when options array is passed', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select', options: [
{ value: 13, label: 'Jane' },
{ value: 22, label: 'Jon' }
]} })
const option = wrapper.find('option[value="22"]')
expect(option.exists()).toBe(true)
expect(option.text()).toBe('Jon')
})
it('renders select list with no options when empty array is passed.', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select', options: []} })
const option = wrapper.find('option')
expect(option.exists()).toBe(false)
})
it('renders select list placeholder option.', () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'select', placeholder: 'Select this', options: []} })
const options = wrapper.findAll('option')
expect(options.length).toBe(1)
expect(options.at(0).attributes('disabled')).toBeTruthy()
})
})