// formApi test import { Form, Select, Button } from '../../index'; import { noop } from 'lodash'; import { sleep as baseSleep } from '../../_test_/utils/index'; const sleep = (ms = 200) => baseSleep(ms); function getForm(props) { return mount(
, { attachTo: document.getElementById('container'), }); } const Option = Select.Option; const FormSelect = ( ); const FormInput = ; const FieldCls = `.semi-form-field`; const fields = ( <> {FormInput} {FormSelect} ); const getDomValue = (field, form) => { let inputDOM = form.find(`[x-field-id="${field}"] input`).getDOMNode(); return inputDOM.getAttribute("value"); }; describe('Form-formApi', () => { beforeEach(() => { document.body.innerHTML = ''; // Avoid `attachTo: document.body` Warning const div = document.createElement('div'); div.setAttribute('id', 'container'); document.body.appendChild(div); }); afterEach(() => { const div = document.getElementById('container'); if (div) { document.body.removeChild(div); } }); it('formApi-getFieldExist', () => { let formApi = null; let getFormApi = api => { formApi = api; }; let spyGet = sinon.spy(getFormApi); let props = { getFormApi: spyGet, children: FormInput, }; const form = getForm(props); expect(formApi.getFieldExist('name')).toEqual(true); expect(formApi.getFieldExist('business')).toEqual(false); }); it('formApi-getInitValue / getInitValues', () => { let formApi = null; let getFormApi = api => { formApi = api; }; let initValues = { name: 'semi', business: 'abc', }; let props = { initValues, getFormApi, children: fields, }; const form = getForm(props); expect(formApi.getInitValue('name')).toEqual('semi'); expect(formApi.getInitValue('business')).toEqual('abc'); expect(formApi.getInitValue('notExistField')).toEqual(undefined); expect(formApi.getInitValue()).toEqual(initValues); expect(formApi.getInitValues()).toEqual(initValues); }); it('formApi-getTouched', () => { let formApi = null; let getFormApi = api => { formApi = api; }; let props = { getFormApi, children: fields, }; const form = getForm(props); let event = {}; form.find(`.semi-input`).simulate('blur', event); expect(formApi.getTouched('name')).toEqual(true); expect(!formApi.getTouched('business')).toEqual(true); }); it('formApi-getValue', () => { let formApi = null; let getFormApi = api => { formApi = api; }; let props = { getFormApi, children: fields, }; const form = getForm(props); // get specific field value expect(formApi.getValue('name')).toEqual(undefined); let event = { target: { value: 'semi' } }; form.find(`.semi-input`).simulate('change', event); expect(formApi.getValue('name')).toEqual('semi'); // get all field's value expect(formApi.getValue()).toEqual({ name: 'semi' }); expect(formApi.getValues()).toEqual({ name: 'semi' }); }); it('formApi-getError', done => { let formApi = null; let getFormApi = api => { formApi = api; }; let errorMessage = 'not muji'; const props = { getFormApi, children: ( value === 'muji', message: errorMessage }]} /> ), }; const form = getForm(props); let event = { target: { value: 'semi' } }; form.find(`.semi-input`).simulate('change', event); setTimeout(() => { expect(formApi.getError('name')).toEqual(errorMessage); done(); }, 300); }); it('formApi-getFormState', done => { let formApi = null; let getFormApi = api => { formApi = api; }; const props = { getFormApi, children: ( value === 'muji', message: 'not muji' }]} /> ), }; const form = getForm(props); let event = { target: { value: 'semi' } }; form.find(`.semi-input`).simulate('change', event); let expectFormState = { values: { name: 'semi' }, errors: { name: 'not muji' }, touched: { name: true }, }; setTimeout(() => { expect(formApi.getFormState()).toEqual(expectFormState); done(); }, 300); }); it('formApi-setError', () => { let formApi = null; let getFormApi = api => { formApi = api; }; const props = { getFormApi, children: , }; const form = getForm(props); let errorMessage = 'not muji'; formApi.setError('name', errorMessage); let expectFormState = { values: {}, errors: { name: errorMessage }, touched: {}, }; expect(formApi.getFormState()).toEqual(expectFormState); form.update(); expect(form.find(`.test .semi-form-field-error-message`).text()).toEqual(errorMessage); }); it('formApi-setTouched', () => { let formApi = null; let getFormApi = api => { formApi = api; }; let props = { getFormApi, children: fields, }; const form = getForm(props); let event = {}; form.find(`.semi-input`).simulate('blur', event); expect(formApi.getTouched('name')).toEqual(true); expect(!formApi.getTouched('business')).toEqual(true); }); it('formApi-setValue', () => { let formApi = null; let getFormApi = api => { formApi = api; }; let props = { getFormApi, children: fields, }; let expectVal = 'semi'; const form = getForm(props); formApi.setValue('name', expectVal); expect(formApi.getValue('name')).toEqual(expectVal); expect(form.find(`.semi-input`).instance().value).toEqual(expectVal); }); it('formApi-reset', () => { let formApi = null; const props = { children: fields, getFormApi: api => { formApi = api; }, initValues: { name: 'a', }, }; const form = getForm(props); let event = { target: { value: 'b' } }; form.find(`.semi-input`).simulate('change', event); formApi.reset(); expect(form.find(`.semi-input`).instance().value).toEqual('a'); expect(formApi.getFormState()).toEqual({ values: { name: 'a' }, errors: {}, touched: {}, }); }); it('formApi-setValues-override', () => { let formApi = null; const props = { children: fields, getFormApi: api => { formApi = api; }, initValues: { name: 'a', extraKeyA: 'uno', }, }; const form = getForm(props); let expectVal = { name: 'semi', business: 'abc', extraKeyB: 'Kay tse', }; formApi.setValues(expectVal, { isOverride: true }); expect(formApi.getValue()).toEqual(expectVal); }); it('formApi-setValues-merge', () => { let formApi = null; let initValues = { name: 'a', extraKeyA: 'uno', }; const props = { children: fields, getFormApi: api => { formApi = api; }, initValues, }; const form = getForm(props); let expectVal = { name: 'semi', business: 'abc', extraKeyB: 'not exist', }; let mergeVal = { name: 'semi', business: 'abc', extraKeyA: 'uno' }; formApi.setValues(expectVal); expect(formApi.getValue()).toEqual(mergeVal); }); it('formApi-validate, validate all field, specail field', async () => { let fields = ( <> val ? '' : 'ab-err'} /> val ? '' : 'ac-err'} /> ) let formApi = null; let getFormApi = api => { formApi = api; }; let formProps = { children: fields, getFormApi, }; let form = getForm(formProps); formApi.validate().then(values=>{}).catch(error=> {}); await sleep(400); expect(formApi.getFormState().errors).toEqual({ a: { b: 'ab-err', c: 'ac-err'}}); formApi.reset(); formApi.validate(['a.c']).then(values=>{}).catch(error=> {}); await sleep(300); expect(formApi.getFormState().errors).toEqual({ a: { c: 'ac-err'}}); }); it('formApi-validate, nested field', async () => { let fields = ( <> val ? '' : 'ab-err'} /> val ? '' : 'ac-err'} /> val ? '' : 'e-err'} /> ) let formApi = null; let getFormApi = api => { formApi = api; }; let formProps = { children: fields, getFormApi, }; let form = getForm(formProps); formApi.validate(['a']).then(values=>{}).catch(error=> {}); await sleep(300); expect(formApi.getFormState().errors).toEqual({ a: { b: 'ab-err', c: 'ac-err' }}); }) it('formApi-setValue, when include nested field', async () => { let fields = ( <> val ? '' : 'ab-err'} /> val ? '' : 'ac-err'} /> val ? '' : 'e-err'} /> ) let formApi = null; let getFormApi = api => { formApi = api; }; let formProps = { children: fields, getFormApi, }; let form = getForm(formProps); formApi.setValue('a', { b: 'semi-b', c: 'semi-c'}) await sleep(300); expect(formApi.getFormState().values).toEqual({ a: { b: 'semi-b', c: 'semi-c' }}); expect(form.find('.ab .semi-input').instance().value).toEqual('semi-b'); expect(form.find('.ac .semi-input').instance().value).toEqual('semi-c'); expect(form.find('.e .semi-input').instance().value).toEqual(''); }); it('formApi-setEror, when include nested field', async () => { let fields = ( <> val ? '' : 'ab-err'} /> val ? '' : 'ac-err'} /> val ? '' : 'e-err'} /> ) let formApi = null; let getFormApi = api => { formApi = api; }; let formProps = { children: fields, getFormApi, }; let form = getForm(formProps); formApi.setError('a', { b: 'ab-err', c: 'ac-err'}); form.update(); await sleep(500); expect(formApi.getFormState().errors).toEqual({ a: { b: 'ab-err', c: 'ac-err' }}); expect(form.find('.ab .semi-form-field-error-message span').at(1).text()).toEqual('ab-err'); expect(form.find('.ac .semi-form-field-error-message span').at(1).text()).toEqual('ac-err'); }); it('formApi-setTouched, when include nested field', async () => { let fields = ( <> val ? '' : 'ab-err'} /> val ? '' : 'ac-err'} /> val ? '' : 'e-err'} /> ) let formApi = null; let getFormApi = api => { formApi = api; }; let formProps = { children: fields, getFormApi, }; let form = getForm(formProps); formApi.setTouched('a', { b: true, c: true }) await sleep(300); expect(formApi.getFormState().touched).toEqual({ a: { b: true, c: true }}); }) it('formApi-setValue, field path precise', () => { // case like: // Exist 3 Field: a.b、a.c、a.d // formApi.setValue('a.b', '123'); let formApi = null; const fields = ( <> ); const props = { children: fields, getFormApi: api => { formApi = api; }, }; const form = getForm(props); formApi.setValue('a.c', 'semi'); // check formState.values let val = formApi.getValue('a.c'); expect(val).toEqual('semi'); form.update(); // check dom render expect(getDomValue('a.c', form)).toEqual('semi'); }); it('formApi-setValue, field path belongs to parent aggregate', () => { // case like: // Exist 3 Field: a.b、a.c、a.d // formApi.setValue('a', { b: 'semi', c: 'design' }); let formApi = null; const fields = ( <> ); const props = { children: fields, getFormApi: api => { formApi = api; }, }; const form = getForm(props); formApi.setValue('a', { b: 'semi', c: 'design' }); let acVal = formApi.getValue('a.c'); let abVal = formApi.getValue('a.b'); expect(abVal).toEqual('semi'); expect(acVal).toEqual('design'); form.update(); // check dom render expect(getDomValue('a.b', form)).toEqual('semi'); expect(getDomValue('a.c', form)).toEqual('design'); }); it('formApi-setValue with array field path, 0 -> 3', () => { const fields = ({ formState, values }) => { return values.a && values.a.map((effect, i) => (
)); }; let formApi = null; const props = { children: fields, getFormApi: api => { formApi = api; }, }; const form = getForm(props); let targetValue = [ { name: '0-name', type: '0-type' }, { name: '1-name', type: '1-type' }, { name: '2-name', type: '2-type' }, ]; formApi.setValue('a', targetValue); let formStateValues = formApi.getValue(); form.update(); // check dom render expect(getDomValue('a[0].name', form)).toEqual('0-name'); expect(getDomValue('a[0].type', form)).toEqual('0-type'); expect(getDomValue('a[1].name', form)).toEqual('1-name'); expect(getDomValue('a[1].type', form)).toEqual('1-type'); expect(getDomValue('a[2].name', form)).toEqual('2-name'); expect(getDomValue('a[2].type', form)).toEqual('2-type'); }); // // this case result was different in cypress / jest, jest result is wrong // it('formApi-setValue with array field path, 3 -> 2, delete some field', done => { // const fields = ({ formState, values }) => { // return values.a && values.a.map((item, i) => ( //
// // //
// )); // }; // let formApi = null; // const props = { // children: fields, // initValues: { // a: [ // { name: '0-name', type: '0-type', key: 0 }, // { name: '1-name', type: '1-type', key: 1 }, // { name: '2-name', type: '2-type', key: 2 }, // ] // }, // getFormApi: api => { // formApi = api; // }, // }; // let form = getForm(props); // // remove middle one // formApi.setValue('a', [ // { name: '0-name', type: '0-type', key: 0 }, // { name: '2-name', type: '2-type', key: 2 }, // ]); // let formStateValues = formApi.getValue(); // form.update(); // setTimeout(() => { // // check dom render // expect(getDomValue('a[0].name', form)).toEqual('0-name'); // expect(getDomValue('a[0].type', form)).toEqual('0-type'); // expect(getDomValue('a[1].name', form)).toEqual('2-name'); // expect(getDomValue('a[1].type', form)).toEqual('2-type'); // expect(form.exists(`[x-field-id="a[2].name"] input`)).toEqual(false); // expect(form.exists(`[x-field-id="a[2].type"] input`)).toEqual(false); // done(); // }, 5000); // }); it('formApi-setValue with array field path, 1 -> 3, add some field', () => { const fields = ({ formState, values }) => { return values.a && values.a.map((effect, i) => (
)); }; let formApi = null; const props = { children: fields, initValues: { a: [{ name: 'semi', type: 'design' }] }, getFormApi: api => { formApi = api; }, }; let form = getForm(props); formApi.setValue('a', [ { name: '0-name', type: '0-type' }, { name: '1-name', type: '1-type' }, { name: '2-name', type: '2-type' }, ]); let formStateValues = formApi.getValue(); form.update(); // check dom render expect(getDomValue('a[0].name', form)).toEqual('0-name'); expect(getDomValue('a[0].type', form)).toEqual('0-type'); expect(getDomValue('a[1].name', form)).toEqual('1-name'); expect(getDomValue('a[1].type', form)).toEqual('1-type'); expect(getDomValue('a[2].name', form)).toEqual('2-name'); expect(getDomValue('a[2].type', form)).toEqual('2-type'); }); // it('formApi-submitForm', () => { // // submit should call validate first // }); });