import { Form, Select } from '../../index'; import { noop } from 'lodash'; import { func } from 'prop-types'; import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants'; function getForm(props) { return mount(
); } function getInput(props) { return ; } const Option = Select.Option; const FormSelect = ( ); const FormInput = ; const FieldCls = `.${BASE_CLASS_PREFIX}-form-field`; const fields = ( <> {FormInput} {FormSelect} ); describe('Form-field', () => { it('className & style & fieldClassName', () => { const fieldProps = { className: 'test-a', style: { color: 'red', }, fieldClassName: 'field-test-b', }; const props = { children: getInput(fieldProps), }; const form = getForm(props); expect(form.exists(`.${BASE_CLASS_PREFIX}-input-wrapper.test-a`)).toEqual(true); expect(form.find(`.${BASE_CLASS_PREFIX}-input-wrapper.test-a`)).toHaveStyle('color', 'red'); expect(form.find(`.${BASE_CLASS_PREFIX}-form-field.field-test-b`).length).toEqual(1); }); it('label', () => { const props = { children: getInput({ label: 'Company', field: 'name', }), }; const form = getForm(props); expect(form.find(`.${BASE_CLASS_PREFIX}-form-field-label`).text()).toEqual('Company'); }); it('labelPosition', () => { // field's labelPosition has a higher weight than form const props = { labelPosition: 'top', children: ( <> {getInput({ labelPosition: 'left', fieldClassName: 'left-input' })} {getInput({ fieldClassName: 'top-input' })} ), }; const form = getForm(props); expect( form .find('.left-input') .instance() .getAttribute('x-label-pos') ).toEqual('left'); expect( form .find('.top-input') .instance() .getAttribute('x-label-pos') ).toEqual('top'); }); it('labelAlign', () => { // field's labelAlign has a higher weight than form const props = { labelAlign: 'right', children: ( <> {getInput({ labelAlign: 'left', fieldClassName: 'left-input' })} {getInput({ fieldClassName: 'right-input' })} ), }; const form = getForm(props); expect(form.exists(`.left-input .${BASE_CLASS_PREFIX}-form-field-label-left`)).toEqual(true); expect(form.exists(`.right-input .${BASE_CLASS_PREFIX}-form-field-label-right`)).toEqual(true); }); it('noLabel', () => { const fieldProps = { noLabel: true, field: 'name', }; const props = { children: getInput(fieldProps), }; const form = getForm(props); expect(form.exists(`.${BASE_CLASS_PREFIX}-form-field-label`)).toEqual(false); }); it('name', () => { const props = { children: getInput({ field: 'name', name: 'company' }), }; const form = getForm(props); expect(form.exists(`.${BASE_CLASS_PREFIX}-form-field.${BASE_CLASS_PREFIX}-form-field-company`)).toEqual(true); }); it('initValue', () => { // field's initValue has a higher weight than form initValues const props = { children: getInput({ initValue: 'b', field: 'name' }), initValues: { name: 'a', }, }; const form = getForm(props); expect(form.find(`.${BASE_CLASS_PREFIX}-input`).instance().value).toEqual('b'); }); it('onChange', () => { const onChange = () => {}; const spyOnChange = sinon.spy(onChange); const fieldProps = { onChange: spyOnChange, field: 'name', }; const props = { children: getInput(fieldProps), }; const form = getForm(props); const event = { target: { value: 'semi' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', event); expect(spyOnChange.calledOnce).toEqual(true); expect(spyOnChange.calledWithMatch('semi')).toEqual(true); }); it('validate-sync', () => { const validate = value => { return value !== 'semi' ? 'invalid' : ''; }; const spyValidate = sinon.spy(validate); const fieldProps = { field: 'name', trigger: 'change', validate: spyValidate, // rules are invalidated when validate is also declared rules: [ { type: 'string', message: 'rules error1' }, { validator: (rule, value) => value === 'muji', message: 'rules error2' }, ], }; const props = { children: getInput(fieldProps), }; const form = getForm(props); // fail const failedEvent = { target: { value: 'milk' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', failedEvent); expect(spyValidate.calledWithMatch('milk')).toEqual(true); expect(form.find(`.${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('invalid'); // success const successEvent = { target: { value: 'semi' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', successEvent); expect(form.exists(`.${BASE_CLASS_PREFIX}-form-field-error-message`)).toEqual(false); }); it('validate-async', done => { const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); const validate = val => { return sleep(50).then(() => { if (val !== 'semi') { return 'invalid'; } return ''; }); }; const spyValidate = sinon.spy(validate); const fieldProps = { trigger: 'change', validate: spyValidate, field: 'name', }; let formApi = null; const getFormApi = api => { formApi = api; }; const props = { getFormApi, children: getInput(fieldProps), }; const form = getForm(props); // fail const failedEvent = { target: { value: 'milk' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', failedEvent); setTimeout(() => { form.update(); expect(spyValidate.firstCall.calledWithMatch('milk')).toEqual(true); expect(formApi.getError('name')).toEqual('invalid'); expect(form.find(`.${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('invalid'); const successEvent = { target: { value: 'semi' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', successEvent); }, 200); setTimeout(() => { form.update(); // success expect(spyValidate.secondCall.calledWithMatch('semi')).toEqual(true); expect(formApi.getError('name')).toEqual(undefined); expect(form.exists(`.${BASE_CLASS_PREFIX}-form-field-error-message`)).toEqual(false); done(); }, 800); }); it('rules', done => { // rules work let fieldProps = { field: 'name', trigger: 'change', rules: [ { type: 'string', message: 'type error' }, { validator: (rule, value) => value === 'muji', message: 'not muji' }, ], }; let formApi = null; const getFormApi = api => { formApi = api; }; const props = { getFormApi, children: getInput(fieldProps), }; const form = getForm(props); const event2 = { target: { value: 2 } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', event2); setTimeout(() => { form.update(); expect(form.find(`.${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('type error, not muji'); }, 50); setTimeout(() => { const event3 = { target: { value: 'semi' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', event3); form.update(); }, 100); setTimeout(() => { // console.log(formApi); expect(form.find(`.${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('not muji'); done(); }, 200); }); it('transform', () => { const transform = stringVal => { return Number(stringVal); }; const validate = value => { return value !== 5 ? 'invalid' : ''; }; const spyValidate = sinon.spy(validate); const fieldProps = { transform, validate: spyValidate, field: 'count', }; let formApi = null; const getFormApi = api => { formApi = api; }; const props = { getFormApi, children: getInput(fieldProps), }; const form = getForm(props); const event = { target: { value: '5' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', event); expect(spyValidate.calledWithMatch(5)).toEqual(true); // only transform value before validate, can't change value in formState expect(formApi.getValue('count')).toEqual('5'); }); it('convert', () => { const convert = stringVal => { return Number(stringVal); }; const spyConvert = sinon.spy(convert); const fieldProps = { convert: spyConvert, field: 'count', }; let formApi = null; const getFormApi = api => { formApi = api; }; const props = { getFormApi, children: getInput(fieldProps), }; const form = getForm(props); const event = { target: { value: '5' } }; form.find(`.${BASE_CLASS_PREFIX}-input`).simulate('change', event); expect(spyConvert.calledWithMatch('5')).toEqual(true); expect(formApi.getValue('count')).toEqual(5); }); it('trigger - mounted / change / blur ', done => { const validate = val => (val !== 'semi' ? 'invalid' : ''); const propsChange = { trigger: 'change', field: 'a', fieldClassName: 'a', validate, }; const propsBlur = { trigger: 'blur', field: 'b', fieldClassName: 'b', initValue: 'milk', validate, }; //TODO mounted const propsMounted = { trigger: 'mounted', field: 'c', fieldClassName: 'c', validate, }; const props = { children: ( <> {getInput(propsChange)} {getInput(propsBlur)} ), }; const form = getForm(props); const event = { target: { value: 'trigger' } }; form.find(`.a .${BASE_CLASS_PREFIX}-input`).simulate('change', event); form.find(`.b .${BASE_CLASS_PREFIX}-input`).simulate('blur', event); setTimeout(() => { form.update(); expect(form.find(`.a .${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('invalid'); expect(form.find(`.b .${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('invalid'); done(); }, 100); }); it('trigger - change & blur', done => { const validate = val => { if (val === 'changeVal') { return 'changeError'; } else if (val === 'blurVal') { return 'blurError'; } else { return ''; } }; const fieldProps = { trigger: ['change', 'blur'], field: 'a', fieldClassName: 'a', validate, }; const props = { children: <>{getInput(fieldProps)}, }; const form = getForm(props); let event = { target: { value: 'changeVal' } }; form.find(`.a .${BASE_CLASS_PREFIX}-input`).simulate('change', event); setTimeout(() => { form.update(); expect(form.find(`.a .${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('changeError'); }, 50); setTimeout(() => { event = { target: { value: 'blurVal' } }; form.find(`.a .${BASE_CLASS_PREFIX}-input`).simulate('change', event); form.find(`.a .${BASE_CLASS_PREFIX}-input`).simulate('blur', {}); }, 80); setTimeout(() => { form.update(); expect(form.find(`.a .${BASE_CLASS_PREFIX}-form-field-error-message`).text()).toEqual('blurError'); done(); }, 100); }); it('field', () => { // 1、username // 2、user[0] // 3、siblings.1 // 4、siblings['2'] // 5、parents[0].name // 6、parents[1]['name'] const fields = ['username', 'user[0]', 'siblings.1', 'siblings[2]', 'parents[0].name', "parents[1]['name']"]; const props = { children: <>{fields.map((field, index) => getInput({ field: field, fieldClassName: `field-${index}` }))}, initValues: { username: 'a', user: ['b'], siblings: [0, 'c', 'd'], parents: [{ name: 'e' }, { name: 'f' }], }, }; const form = getForm(props); // If you do not pass a specific label prop, the label content is consistent with the field const fieldsDOM = form.find(`.${BASE_CLASS_PREFIX}-form-field .${BASE_CLASS_PREFIX}-input`); expect(fieldsDOM.at(0).instance().value).toEqual('a'); expect(fieldsDOM.at(1).instance().value).toEqual('b'); expect(fieldsDOM.at(2).instance().value).toEqual('c'); expect(fieldsDOM.at(3).instance().value).toEqual('d'); expect(fieldsDOM.at(4).instance().value).toEqual('e'); expect(fieldsDOM.at(5).instance().value).toEqual('f'); }); // TODO // it('allowEmptyString', () => {}); // it('extraText') // it('extraTextPosition') // it('helpText') // it('stopValidateWithError') // it('noErrorMessage) // it('pure') // it('fieldStyle') });