Skip to content

Commit 39ced98

Browse files
authored
Merge pull request #12 from kevinkosterr/8-tests
Add tests, tests scripts and apply fixes
2 parents 76b0440 + 10eea8a commit 39ced98

24 files changed

+1961
-32
lines changed

__tests__/_resources/utils.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { mount } from '@vue/test-utils'
2+
3+
import FormGenerator from '@/FormGenerator.vue'
4+
5+
/**
6+
* Mount the form generator component
7+
* @param schema - schema object to pass as prop
8+
* @param {Object} model - model object to pass as prop
9+
* @returns {VueWrapper<FormGenerator>}
10+
*/
11+
export function mountFormGenerator (schema, model) {
12+
return mount(FormGenerator, { props: { schema, model } })
13+
}
14+
15+
/**
16+
* Generate a form schema for a single field component
17+
* @param {String} name - name of the field
18+
* @param {String} model - model key of the field
19+
* @param {String} type - field type
20+
* @param {String} inputType - field input type, required if `type === 'input'`
21+
* @param {String} label - field label
22+
* @param {any} initialValue - initial model value
23+
* @param {Object} extraFieldProperties - extra field properties to add
24+
* @returns {{schema: {fields: [{name, model, inputType, label, type}]}, model: {}}}
25+
*/
26+
export function generateSchemaSingleField (
27+
name,
28+
model,
29+
type,
30+
inputType,
31+
label,
32+
initialValue,
33+
extraFieldProperties
34+
) {
35+
return {
36+
model: {
37+
[model]: initialValue
38+
},
39+
schema: {
40+
fields: [
41+
{
42+
name, model, type, inputType, label, ...extraFieldProperties
43+
}
44+
]
45+
}
46+
}
47+
}
48+
49+
/**
50+
* Generate props for a single field component
51+
* @param {Object} formSchema - entire form schema object
52+
* @returns {{field: *, model, id: string, formGenerator: {}}}
53+
*/
54+
export function generatePropsSingleField (formSchema) {
55+
return {
56+
id: formSchema.name + '_test_id',
57+
formGenerator: {},
58+
field: { ...formSchema.schema.fields[0] },
59+
model: { ...formSchema.model }
60+
}
61+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { mountFormGenerator, generatePropsSingleField } from '@test/_resources/utils.js'
2+
import { describe, it, expect } from 'vitest'
3+
import { mount, config } from '@vue/test-utils'
4+
5+
import FieldButton from '@/fields/buttons/FieldButton.vue'
6+
import FieldPassword from '@/fields/input/FieldPassword.vue'
7+
import FieldCheckbox from '@/fields/input/FieldCheckbox.vue'
8+
9+
const form = {
10+
model: {
11+
password: '',
12+
checkboxTestModel: false
13+
},
14+
schema: {
15+
fields: [
16+
{
17+
type: 'button',
18+
buttonText: 'Reset password field',
19+
onClick: (model, _field) => {
20+
model.password = ''
21+
}
22+
},
23+
{
24+
name: 'checkboxTestName',
25+
model: 'checkboxTestModel',
26+
label: 'Checkbox Test',
27+
type: 'checkbox'
28+
},
29+
{
30+
name: 'passwordTest',
31+
model: 'password',
32+
label: 'Password',
33+
type: 'input',
34+
inputType: 'password'
35+
}
36+
]
37+
}
38+
}
39+
40+
const props = generatePropsSingleField(form)
41+
42+
43+
describe('Test FieldButton', () => {
44+
45+
it('Should render correctly', () => {
46+
const wrapper = mount(FieldButton, { props })
47+
expect(wrapper.find('button').exists()).toBe(true)
48+
expect(wrapper.find('button').element.innerHTML).toContain(props.field.buttonText)
49+
})
50+
51+
it('Should render correctly inside form generator', async () => {
52+
config.global.components = { FieldButton }
53+
54+
const formWrapper = mountFormGenerator(form.schema, form.model)
55+
const buttonField = formWrapper.findComponent(FieldButton)
56+
expect(buttonField.exists()).toBeTruthy()
57+
expect(buttonField.find('button').element.innerHTML).toContain(props.field.buttonText)
58+
})
59+
60+
it('Should update model values', async () => {
61+
config.global.components = { FieldPassword, FieldButton, FieldCheckbox }
62+
63+
const formWrapper = mountFormGenerator(form.schema, form.model)
64+
expect(formWrapper.find('input[type=password]').exists()).toBe(true)
65+
expect(formWrapper.find('input[type=checkbox]').exists()).toBe(true)
66+
expect(formWrapper.find('button').exists()).toBe(true)
67+
68+
await formWrapper.find('input[type=password]').setValue('password')
69+
expect(formWrapper.vm.model.password).toBe('password')
70+
71+
const buttonField = formWrapper.findComponent(FieldButton)
72+
expect(buttonField.exists()).toBe(true)
73+
74+
await buttonField.find('button').trigger('click.prevent')
75+
expect(formWrapper.vm.model.password).toBe('')
76+
})
77+
78+
})
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { generatePropsSingleField, generateSchemaSingleField, mountFormGenerator } from '@test/_resources/utils.js'
2+
import { describe, it, expect } from 'vitest'
3+
import { mount, config } from '@vue/test-utils'
4+
5+
import FieldCheckbox from '@/fields/input/FieldCheckbox.vue'
6+
7+
const form = generateSchemaSingleField(
8+
'checkboxTestName',
9+
'checkboxTestModel',
10+
'input',
11+
'checkbox',
12+
'Checkbox Test',
13+
false
14+
)
15+
16+
const props = generatePropsSingleField(form)
17+
18+
describe('Test FieldCheckbox', () => {
19+
20+
it('Should render correctly', async () => {
21+
const wrapper = mount(FieldCheckbox, { props })
22+
// Checkbox should be rendered.
23+
expect(wrapper.find('input[type=checkbox]').exists()).toBe(true)
24+
// Label should be rendered and have the correct text.
25+
expect(wrapper.find('label').text()).toContain(props.field.label)
26+
await wrapper.vm.$nextTick()
27+
// Checked attribute should be false, since the default value is set to false inside the model.
28+
expect(wrapper.find('input[type=checkbox]').element.checked).toBe(false)
29+
})
30+
31+
it('Should render correctly inside form generator', async() => {
32+
config.global.components = { FieldCheckbox }
33+
const formWrapper = mountFormGenerator(form.schema, form.model)
34+
35+
expect(formWrapper.findComponent(FieldCheckbox).exists()).toBe(true)
36+
expect(formWrapper.find('input[type=checkbox]').exists()).toBe(true)
37+
})
38+
39+
it('Should be disabled, when specified with a conditional function', async () => {
40+
const model = { ...form.model, otherTestProperty: false }
41+
const disabled = (model, _field) => model.otherTestProperty === false
42+
const field = { ...form.schema.fields[0], disabled }
43+
44+
expect(disabled(model)).toBe(true)
45+
46+
const wrapper = mount(FieldCheckbox, { props: { ...props, model, field } })
47+
expect(wrapper.find('input[type=checkbox]').exists()).toBe(true)
48+
await wrapper.vm.$nextTick()
49+
50+
expect(wrapper.vm.isDisabled).toBe(true)
51+
expect(wrapper.find('input[type=checkbox]').element.disabled).toBe(true)
52+
})
53+
54+
it('Should be disabled, when specified with boolean', async () => {
55+
const field = { ...props.field, disabled: true }
56+
const wrapper = mount(FieldCheckbox, { props: { ...props, field } })
57+
58+
const checkbox = wrapper.find('input[type=checkbox]')
59+
60+
expect(checkbox.exists()).toBe(true)
61+
expect(wrapper.vm.isDisabled).toBe(true)
62+
63+
await wrapper.vm.$nextTick()
64+
65+
expect(wrapper.find('input[type=checkbox]').element.disabled).toBe(true)
66+
})
67+
68+
it('Checked state should be the same as default value', async () => {
69+
const model = { checkboxTestModel: true }
70+
const wrapper = mount(FieldCheckbox, { props: { ...props, model } })
71+
72+
await wrapper.vm.$nextTick()
73+
74+
expect(wrapper.find('input[type=checkbox]').element.checked).toBe(model.checkboxTestModel)
75+
})
76+
77+
it('Should emit onInput event', async () => {
78+
const wrapper = mount(FieldCheckbox, { props })
79+
await wrapper.find('input[type=checkbox]').trigger('change' )
80+
expect(wrapper.emitted()).toHaveProperty('onInput')
81+
})
82+
83+
it('Should update model value', async () => {
84+
config.global.components = { FieldCheckbox }
85+
86+
const formWrapper = mountFormGenerator(form.schema, form.model)
87+
88+
89+
const wrapper = formWrapper.findComponent(FieldCheckbox)
90+
expect(wrapper.exists()).toBe(true)
91+
92+
await wrapper.vm.$nextTick()
93+
expect(wrapper.find('input').element.checked).toBe(false)
94+
95+
await wrapper.find('input').trigger('click')
96+
expect(wrapper.find('input').element.checked).toBe(true)
97+
98+
await wrapper.find('input').trigger('change')
99+
expect(wrapper.emitted()).toHaveProperty('onInput', [ [ true ] ])
100+
await wrapper.vm.$nextTick()
101+
102+
expect(formWrapper.vm.model.checkboxTestModel).toBe(true)
103+
// Model value of wrapper should be updated as well, since this gets passed down from the Form Generator.
104+
expect(wrapper.vm.model.checkboxTestModel).toBe(true)
105+
})
106+
107+
})
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { mountFormGenerator, generatePropsSingleField, generateSchemaSingleField } from '@test/_resources/utils.js'
2+
import { mount, config } from '@vue/test-utils'
3+
import { describe, it, expect } from 'vitest'
4+
5+
import FieldColor from '@/fields/input/FieldColor.vue'
6+
7+
const form = generateSchemaSingleField(
8+
'testColor',
9+
'colorModel',
10+
'input',
11+
'color',
12+
'Pick a color',
13+
''
14+
)
15+
16+
const props = generatePropsSingleField(form)
17+
18+
describe('Test FieldColor', () => {
19+
20+
it('Should render correctly', async () => {
21+
const wrapper = mount(FieldColor, { props })
22+
expect(wrapper.find('input[type=color]').exists()).toBe(true)
23+
})
24+
25+
it('Should render correctly inside form generator', async () => {
26+
config.global.components = { FieldColor }
27+
28+
const formWrapper = mountFormGenerator(form.schema, form.model)
29+
expect(formWrapper.findComponent(FieldColor).exists()).toBe(true)
30+
expect(formWrapper.find('input[type=color]').exists()).toBe(true)
31+
})
32+
33+
it('Should emit onInput event', async () => {
34+
const wrapper = mount(FieldColor, { props })
35+
await wrapper.find('input[type=color]').trigger('change')
36+
expect(wrapper.emitted()).toHaveProperty('onInput')
37+
})
38+
39+
it('Should update model value', async () => {
40+
config.global.components = { FieldColor }
41+
42+
const formWrapper = mountFormGenerator(form.schema, form.model)
43+
44+
const wrapper = formWrapper.findComponent(FieldColor)
45+
await wrapper.find('input[type=color]').setValue('#efefef')
46+
expect(wrapper.emitted()).toHaveProperty('onInput', [ [ '#efefef' ] ])
47+
expect(formWrapper.vm.model.colorModel).toBe('#efefef')
48+
})
49+
50+
})
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { describe, it, expect } from 'vitest'
2+
import { mountFormGenerator, generatePropsSingleField, generateSchemaSingleField } from '@test/_resources/utils.js'
3+
import { mount, config } from '@vue/test-utils'
4+
5+
import FieldNumber from '@/fields/input/FieldNumber.vue'
6+
7+
const form = generateSchemaSingleField(
8+
'testNumber',
9+
'numberModel',
10+
'input',
11+
'number',
12+
'Number input',
13+
0,
14+
{
15+
max: 5,
16+
min: 2
17+
}
18+
)
19+
20+
const props = generatePropsSingleField(form)
21+
22+
describe('Test FieldNumber', () => {
23+
24+
it('Should render correctly', async () => {
25+
const wrapper = mount(FieldNumber, { props })
26+
expect(wrapper.find('input[type=number]').exists()).toBeTruthy()
27+
})
28+
29+
it('Should render correctly inside form generator', async () => {
30+
config.global.components = { FieldNumber }
31+
const formWrapper = mountFormGenerator(form.schema, form.model)
32+
expect(formWrapper.find('input[type=number]').exists()).toBeTruthy()
33+
34+
const wrapper = formWrapper.findComponent(FieldNumber)
35+
expect(wrapper.exists()).toBeTruthy()
36+
expect(wrapper.attributes().min).toBe('2')
37+
expect(wrapper.attributes().max).toBe('5')
38+
})
39+
40+
it('Should emit onInput event', async () => {
41+
const wrapper = mount(FieldNumber, { props })
42+
await wrapper.find('input').trigger('input')
43+
expect(wrapper.emitted()).toHaveProperty('onInput')
44+
})
45+
46+
it('Should update model value', async () => {
47+
config.global.components = { FieldNumber }
48+
49+
const formWrapper = mountFormGenerator(form.schema, form.model)
50+
const numberField = formWrapper.findComponent(FieldNumber)
51+
expect(numberField.exists()).toBeTruthy()
52+
53+
await numberField.find('input').setValue(4)
54+
expect(formWrapper.vm.model.numberModel).toBe(4)
55+
})
56+
})

0 commit comments

Comments
 (0)