test(Form): migrate more legacy test cases (#9704)

This commit is contained in:
neverland 2021-10-20 17:44:05 +08:00 committed by GitHub
parent 330084d7f7
commit 881f742818
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 355 additions and 383 deletions

View File

@ -22,15 +22,15 @@ test('should emit submit event when submitting form', async () => {
test('should emit failed event when validating failed', async () => {
const onFailed = jest.fn();
const wrapper = mountSimpleRulesForm({
const { form } = mountSimpleRulesForm({
methods: {
onFailed,
},
});
await submitForm(wrapper);
await submitForm(form);
expect(wrapper.html()).toMatchSnapshot();
expect(form.html()).toMatchSnapshot();
expect(onFailed).toHaveBeenCalledWith({
errors: [
{ name: 'A', message: 'A failed' },

View File

@ -1,212 +0,0 @@
import { mountForm, submitForm } from './shared';
function mountFormWithChild({ template, data }) {
const onSubmit = jest.fn();
const onFailed = jest.fn();
const wrapper = mountForm({
template: `
<van-form @submit="onSubmit" @failed="onFailed">
<van-field name="A" :rules="[{ required: true, message: 'foo' }]">
<template #input>${template}</template>
</van-field>
<van-button native-type="submit" />
</van-form>
`,
data,
methods: {
onSubmit,
onFailed,
},
});
return {
wrapper,
onSubmit,
onFailed,
};
}
test('use switch', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: '<van-switch v-model="value" />',
data() {
return { value: false };
},
});
await submitForm(wrapper);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: false },
});
wrapper.setData({ value: true });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: true });
});
test('use checkbox', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: '<van-checkbox v-model="value" />',
data() {
return { value: false };
},
});
await submitForm(wrapper);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: false },
});
wrapper.setData({ value: true });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: true });
});
test('use checkbox-group', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: `
<van-checkbox-group v-model="checkboxGroup">
<van-checkbox name="1">1</van-checkbox>
<van-checkbox name="2">2</van-checkbox>
</van-checkbox-group>
`,
data() {
return { checkboxGroup: [] };
},
});
await submitForm(wrapper);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: [] },
});
wrapper.setData({ checkboxGroup: ['1'] });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: ['1'] });
});
test('use radio', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: `
<van-radio-group v-model="radio">
<van-radio name="1">1</van-radio>
<van-radio name="2">2</van-radio>
</van-radio-group>
`,
data() {
return { radio: '' };
},
});
await submitForm(wrapper);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: '' },
});
wrapper.setData({ radio: '1' });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: '1' });
});
test('use stepper', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: '<van-stepper v-model="value" :min="0" />',
data() {
return { value: 0 };
},
});
await submitForm(wrapper);
expect(onFailed).toBeCalledTimes(0);
wrapper.setData({ value: 1 });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: 1 });
});
test('use rate', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: '<van-rate v-model="value" />',
data() {
return { value: 0 };
},
});
await submitForm(wrapper);
expect(onFailed).toBeCalledTimes(0);
wrapper.setData({ value: 1 });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: 1 });
});
test('use slider', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: '<van-slider v-model="value" />',
data() {
return { value: 0 };
},
});
await submitForm(wrapper);
expect(onFailed).toBeCalledTimes(0);
wrapper.setData({ value: 50 });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: 50 });
});
test('use uploader', async () => {
const { wrapper, onSubmit, onFailed } = mountFormWithChild({
template: '<van-uploader v-model="value" />',
data() {
return { value: [] };
},
});
await submitForm(wrapper);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: [] },
});
wrapper.setData({ value: [{ url: 'foo' }] });
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: [{ url: 'foo' }] });
});
test('should not get formValue from button slot', async () => {
const onSubmit = jest.fn();
const wrapper = mountForm({
template: `
<van-form @submit="onSubmit">
<van-field name="A" value="foo" :rules="[{ required: true, message: 'foo' }]">
<template #button>
<van-checkbox :value="false" />
</template>
</van-field>
<van-button native-type="submit" />
</van-form>
`,
methods: {
onSubmit,
},
});
await submitForm(wrapper);
expect(onSubmit).toHaveBeenCalledWith({ A: 'foo' });
});

View File

@ -0,0 +1,201 @@
import { ref } from 'vue';
import { mount, later } from '../../../test';
import { submitForm } from './shared';
import { Form } from '..';
import { Rate } from '../../rate';
import { Field } from '../../field';
import { Radio } from '../../radio';
import { Switch } from '../../switch';
import { Slider } from '../../slider';
import { Stepper } from '../../stepper';
import { Checkbox } from '../../checkbox';
import { RadioGroup } from '../../radio-group';
import { CheckboxGroup } from '../../checkbox-group';
import { Uploader, UploaderFileListItem } from '../../uploader';
function mountFormWithChild(input: () => JSX.Element) {
const onSubmit = jest.fn();
const onFailed = jest.fn();
const form = mount({
render() {
return (
<Form onSubmit={onSubmit} onFailed={onFailed}>
<Field
v-slots={{ input }}
name="A"
rules={[{ required: true, message: 'foo' }]}
/>
</Form>
);
},
});
return {
form,
onSubmit,
onFailed,
};
}
test('should allow to use Switch as a form item', async () => {
const switched = ref(false);
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<Switch v-model={switched.value} />
));
await submitForm(form);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: false },
});
switched.value = true;
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: true });
});
test('should allow to use Checkbox as a form item', async () => {
const checked = ref(false);
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<Checkbox v-model={checked.value} />
));
await submitForm(form);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: false },
});
checked.value = true;
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: true });
});
test('should allow to use CheckboxGroup as a form item', async () => {
const checked = ref<string[]>([]);
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<CheckboxGroup v-model={checked.value}>
<Checkbox name="1">1</Checkbox>
<Checkbox name="2">2</Checkbox>
</CheckboxGroup>
));
await submitForm(form);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: [] },
});
checked.value = ['1'];
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: ['1'] });
});
test('should allow to use RadioGroup as a form item', async () => {
const checked = ref('');
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<RadioGroup v-model={checked.value}>
<Radio name="1">1</Radio>
<Radio name="2">2</Radio>
</RadioGroup>
));
await submitForm(form);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: '' },
});
checked.value = '1';
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: '1' });
});
test('should allow to use Stepper as a form item', async () => {
const value = ref(0);
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<Stepper v-model={value.value} min="0" />
));
await submitForm(form);
expect(onFailed).toBeCalledTimes(0);
value.value = 1;
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: 1 });
});
test('should allow to use Rate as a form item', async () => {
const rate = ref(0);
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<Rate v-model={rate.value} />
));
await submitForm(form);
expect(onFailed).toBeCalledTimes(0);
rate.value = 1;
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: 1 });
});
test('should allow to use Slider as a form item', async () => {
const value = ref(0);
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<Slider v-model={value.value} />
));
await submitForm(form);
expect(onFailed).toBeCalledTimes(0);
value.value = 50;
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: 50 });
});
test('should allow to use Uploader as a form item', async () => {
const fileList = ref<UploaderFileListItem[]>([]);
const { form, onSubmit, onFailed } = mountFormWithChild(() => (
<Uploader v-model={fileList.value} />
));
await submitForm(form);
expect(onFailed).toHaveBeenCalledWith({
errors: [{ message: 'foo', name: 'A' }],
values: { A: [] },
});
fileList.value = [{ url: 'foo' }];
await later();
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: [{ url: 'foo' }] });
});
test('should not get formValue from button slot', async () => {
const onSubmit = jest.fn();
const form = mount({
render() {
return (
<Form onSubmit={onSubmit}>
<Field
v-slots={{ button: () => <Checkbox modelValue={false} /> }}
name="A"
rules={[{ required: true, message: 'foo' }]}
modelValue="foo"
/>
</Form>
);
},
});
await submitForm(form);
expect(onSubmit).toHaveBeenCalledWith({ A: 'foo' });
});

View File

@ -1,164 +0,0 @@
import { later, mockScrollIntoView } from '../../../test';
import { mountForm, mountSimpleRulesForm, getSimpleRules } from './shared';
test('submit method', async () => {
const onSubmit = jest.fn();
mountForm({
template: `
<van-form ref="form" @submit="onSubmit">
<van-field name="A" value="bar" />
<van-button native-type="submit" />
</van-form>
`,
mounted() {
this.$refs.form.submit();
},
methods: {
onSubmit,
},
});
await later();
expect(onSubmit).toHaveBeenCalledWith({ A: 'bar' });
});
test('validate method - validate all fields', (done) => {
mountSimpleRulesForm({
mounted() {
this.$refs.form.validate().catch((err) => {
expect(err).toEqual([
{ message: 'A failed', name: 'A' },
{ message: 'B failed', name: 'B' },
]);
done();
});
},
});
});
test('validate method - validate one field and failed', (done) => {
mountSimpleRulesForm({
mounted() {
this.$refs.form.validate('A').catch((err) => {
expect(err).toEqual({ message: 'A failed', name: 'A' });
done();
});
},
});
});
test('validate method - validate one field and passed', (done) => {
mountForm({
template: `
<van-form ref="form" @failed="onFailed">
<van-field name="A" :rules="rulesA" value="123" />
<van-field name="B" :rules="rulesB" value="" />
<van-button native-type="submit" />
</van-form>
`,
data: getSimpleRules,
mounted() {
this.$refs.form.validate('A').then(done);
},
});
});
test('validate method - validate two fields and failed', (done) => {
mountForm({
template: `
<van-form ref="form" @failed="onFailed">
<van-field name="A" :rules="rulesA" value="123" />
<van-field name="B" :rules="rulesB" value="" />
<van-button native-type="submit" />
</van-form>
`,
data: getSimpleRules,
mounted() {
this.$refs.form.validate(['A', 'B']).catch((error) => {
expect(error).toEqual([{ message: 'B failed', name: 'B' }]);
done();
});
},
});
});
test('validate method - unexisted name', (done) => {
mountSimpleRulesForm({
mounted() {
this.$refs.form.validate('unexisted').catch(done);
},
});
});
test('resetValidation method - reset all fields', (done) => {
const wrapper = mountSimpleRulesForm({
mounted() {
this.$refs.form.validate().catch(() => {
this.$refs.form.resetValidation();
const errors = wrapper.findAll('.van-field__error-message');
expect(errors.length).toEqual(0);
done();
});
},
});
});
test('resetValidation method - reset two fields', (done) => {
const wrapper = mountSimpleRulesForm({
mounted() {
this.$refs.form.validate().catch(() => {
this.$refs.form.resetValidation(['A', 'B']);
const errors = wrapper.findAll('.van-field__error-message');
expect(errors.length).toEqual(0);
done();
});
},
});
});
test('resetValidation method - reset one field', (done) => {
const wrapper = mountSimpleRulesForm({
mounted() {
this.$refs.form.validate().catch(() => {
this.$refs.form.resetValidation('A');
expect(wrapper.findAll('.van-field--error').length).toEqual(1);
this.$refs.form.resetValidation('B');
expect(wrapper.findAll('.van-field--error').length).toEqual(0);
done();
});
},
});
});
test('resetValidation method - reset when rule message is empty', (done) => {
const wrapper = mountSimpleRulesForm({
data() {
return {
rulesA: [{ required: true, message: '' }],
rulesB: [{ required: true, message: '' }],
};
},
mounted() {
this.$refs.form.validate().catch(() => {
this.$refs.form.resetValidation('A');
expect(wrapper.findAll('.van-field--error').length).toEqual(1);
done();
});
},
});
});
test('scrollToField method', (done) => {
const fn = mockScrollIntoView();
mountSimpleRulesForm({
mounted() {
this.$refs.form.scrollToField('unknown');
expect(fn).toHaveBeenCalledTimes(0);
this.$refs.form.scrollToField('A');
expect(fn).toHaveBeenCalledTimes(1);
done();
},
});
});

View File

@ -0,0 +1,139 @@
import { ref } from 'vue';
import { mount, later, mockScrollIntoView } from '../../../test';
import { mountSimpleRulesForm, getSimpleRules } from './shared';
import { Form, FormInstance } from '..';
import { Field } from '../../field';
test('should emit submit event after calling the submit method', async () => {
const onSubmit = jest.fn();
const form = ref<FormInstance>();
mount({
render() {
return (
<Form ref={form} onSubmit={onSubmit}>
<Field name="A" modelValue="bar" />
</Form>
);
},
});
form.value?.submit();
await later();
expect(onSubmit).toHaveBeenCalledWith({ A: 'bar' });
});
test('validate method - validate all fields', async () => {
const { formRef } = mountSimpleRulesForm();
try {
await formRef.value?.validate();
} catch (err) {
expect(err).toEqual([
{ message: 'A failed', name: 'A' },
{ message: 'B failed', name: 'B' },
]);
}
});
test('validate method - validate one field and failed', async () => {
const { formRef } = mountSimpleRulesForm();
try {
await formRef.value?.validate('A');
} catch (err) {
expect(err).toEqual({ message: 'A failed', name: 'A' });
}
});
test('validate method - validate one field and passed', () => {
const formRef = ref<FormInstance>();
mount({
render() {
return (
<Form ref={formRef}>
<Field name="A" rules={this.rulesA} modelValue="123" />
<Field name="B" rules={this.rulesB} modelValue="" />
</Form>
);
},
data: getSimpleRules,
});
expect(async () => formRef.value?.validate('A')).not.toThrowError();
});
test('validate method - validate two fields and failed', async () => {
const formRef = ref<FormInstance>();
mount({
render() {
return (
<Form ref={formRef}>
<Field name="A" rules={this.rulesA} modelValue="123" />
<Field name="B" rules={this.rulesB} modelValue="" />
</Form>
);
},
data: getSimpleRules,
});
try {
await formRef.value?.validate(['A', 'B']);
} catch (err) {
expect(err).toEqual([{ message: 'B failed', name: 'B' }]);
}
});
test('validate method - unexist name', (done) => {
const { formRef } = mountSimpleRulesForm();
formRef.value?.validate('unexist').catch(done);
});
test('resetValidation method - reset all fields', async () => {
const { form, formRef } = mountSimpleRulesForm();
try {
await formRef.value?.validate();
} catch (err) {
formRef.value?.resetValidation();
await later();
const errors = form.findAll('.van-field__error-message');
expect(errors.length).toEqual(0);
}
});
test('resetValidation method - reset two fields', async () => {
const { form, formRef } = mountSimpleRulesForm();
try {
await formRef.value?.validate();
} catch (err) {
formRef.value?.resetValidation(['A', 'B']);
await later();
const errors = form.findAll('.van-field__error-message');
expect(errors.length).toEqual(0);
}
});
test('resetValidation method - reset one field', async () => {
const { form, formRef } = mountSimpleRulesForm();
try {
await formRef.value?.validate();
} catch (err) {
formRef.value?.resetValidation('A');
await later();
expect(form.findAll('.van-field__error-message').length).toEqual(1);
formRef.value?.resetValidation('B');
await later();
expect(form.findAll('.van-field__error-message').length).toEqual(0);
}
});
test('scrollToField method', () => {
const fn = mockScrollIntoView();
const { formRef } = mountSimpleRulesForm();
formRef.value?.scrollToField('unknown');
expect(fn).toHaveBeenCalledTimes(0);
formRef.value?.scrollToField('A');
expect(fn).toHaveBeenCalledTimes(1);
});

View File

@ -1,5 +1,6 @@
import { ref } from 'vue';
import { mount, later } from '../../../test';
import { Form } from '..';
import { Form, FormInstance } from '..';
import { Field } from '../../field';
import type { VueWrapper } from '@vue/test-utils';
@ -15,11 +16,13 @@ export function getSimpleRules() {
};
}
export function mountSimpleRulesForm(options: any) {
return mount({
export function mountSimpleRulesForm(options: any = {}) {
const formRef = ref<FormInstance>();
const form = mount({
render() {
const onFailed = 'onFailed' in this ? this.onFailed : () => {};
return (
<Form ref="form" onFailed={this.onFailed}>
<Form ref={formRef} onFailed={onFailed}>
<Field name="A" rules={this.rulesA} modelValue="" />
<Field name="B" rules={this.rulesB} modelValue="" />
</Form>
@ -28,4 +31,9 @@ export function mountSimpleRulesForm(options: any) {
data: getSimpleRules,
...options,
});
return {
form,
formRef,
};
}