formApi.test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. // formApi test
  2. import { Form, Select, Button } from '../../index';
  3. import { noop } from 'lodash';
  4. import { sleep as baseSleep } from '../../_test_/utils/index';
  5. const sleep = (ms = 200) => baseSleep(ms);
  6. function getForm(props) {
  7. return mount(<Form {...props}></Form>, {
  8. attachTo: document.getElementById('container'),
  9. });
  10. }
  11. const Option = Select.Option;
  12. const FormSelect = (
  13. <Form.Select label="business" field="business" style={{ width: 200 }}>
  14. <Option value="abc">Abc</Option>
  15. <Option value="hotsoon">Hotsoon</Option>
  16. <Option value="topbuzz">TopBuzz</Option>
  17. </Form.Select>
  18. );
  19. const FormInput = <Form.Input field="name" />;
  20. const FieldCls = `.semi-form-field`;
  21. const fields = (
  22. <>
  23. {FormInput}
  24. {FormSelect}
  25. </>
  26. );
  27. describe('Form-formApi', () => {
  28. beforeEach(() => {
  29. document.body.innerHTML = '';
  30. // Avoid `attachTo: document.body` Warning
  31. const div = document.createElement('div');
  32. div.setAttribute('id', 'container');
  33. document.body.appendChild(div);
  34. });
  35. afterEach(() => {
  36. const div = document.getElementById('container');
  37. if (div) {
  38. document.body.removeChild(div);
  39. }
  40. });
  41. it('formApi-getFieldExist', () => {
  42. let formApi = null;
  43. let getFormApi = api => {
  44. formApi = api;
  45. };
  46. let spyGet = sinon.spy(getFormApi);
  47. let props = {
  48. getFormApi: spyGet,
  49. children: FormInput,
  50. };
  51. const form = getForm(props);
  52. expect(formApi.getFieldExist('name')).toEqual(true);
  53. expect(formApi.getFieldExist('business')).toEqual(false);
  54. });
  55. it('formApi-getInitValue / getInitValues', () => {
  56. let formApi = null;
  57. let getFormApi = api => {
  58. formApi = api;
  59. };
  60. let initValues = {
  61. name: 'semi',
  62. business: 'abc',
  63. };
  64. let props = {
  65. initValues,
  66. getFormApi,
  67. children: fields,
  68. };
  69. const form = getForm(props);
  70. expect(formApi.getInitValue('name')).toEqual('semi');
  71. expect(formApi.getInitValue('business')).toEqual('abc');
  72. expect(formApi.getInitValue('notExistField')).toEqual(undefined);
  73. expect(formApi.getInitValue()).toEqual(initValues);
  74. expect(formApi.getInitValues()).toEqual(initValues);
  75. });
  76. it('formApi-getTouched', () => {
  77. let formApi = null;
  78. let getFormApi = api => {
  79. formApi = api;
  80. };
  81. let props = {
  82. getFormApi,
  83. children: fields,
  84. };
  85. const form = getForm(props);
  86. let event = {};
  87. form.find(`.semi-input`).simulate('blur', event);
  88. expect(formApi.getTouched('name')).toEqual(true);
  89. expect(!formApi.getTouched('business')).toEqual(true);
  90. });
  91. it('formApi-getValue', () => {
  92. let formApi = null;
  93. let getFormApi = api => {
  94. formApi = api;
  95. };
  96. let props = {
  97. getFormApi,
  98. children: fields,
  99. };
  100. const form = getForm(props);
  101. // get specific field value
  102. expect(formApi.getValue('name')).toEqual(undefined);
  103. let event = { target: { value: 'semi' } };
  104. form.find(`.semi-input`).simulate('change', event);
  105. expect(formApi.getValue('name')).toEqual('semi');
  106. // get all field's value
  107. expect(formApi.getValue()).toEqual({ name: 'semi' });
  108. expect(formApi.getValues()).toEqual({ name: 'semi' });
  109. });
  110. it('formApi-getError', done => {
  111. let formApi = null;
  112. let getFormApi = api => {
  113. formApi = api;
  114. };
  115. let errorMessage = 'not muji';
  116. const props = {
  117. getFormApi,
  118. children: (
  119. <Form.Input
  120. trigger="change"
  121. field="name"
  122. rules={[{ validator: (rule, value) => value === 'muji', message: errorMessage }]}
  123. />
  124. ),
  125. };
  126. const form = getForm(props);
  127. let event = { target: { value: 'semi' } };
  128. form.find(`.semi-input`).simulate('change', event);
  129. setTimeout(() => {
  130. expect(formApi.getError('name')).toEqual(errorMessage);
  131. done();
  132. }, 300);
  133. });
  134. it('formApi-getFormState', done => {
  135. let formApi = null;
  136. let getFormApi = api => {
  137. formApi = api;
  138. };
  139. const props = {
  140. getFormApi,
  141. children: (
  142. <Form.Input
  143. trigger="change"
  144. field="name"
  145. rules={[{ validator: (rule, value) => value === 'muji', message: 'not muji' }]}
  146. />
  147. ),
  148. };
  149. const form = getForm(props);
  150. let event = { target: { value: 'semi' } };
  151. form.find(`.semi-input`).simulate('change', event);
  152. let expectFormState = {
  153. values: { name: 'semi' },
  154. errors: { name: 'not muji' },
  155. touched: { name: true },
  156. };
  157. setTimeout(() => {
  158. expect(formApi.getFormState()).toEqual(expectFormState);
  159. done();
  160. }, 300);
  161. });
  162. it('formApi-setError', () => {
  163. let formApi = null;
  164. let getFormApi = api => {
  165. formApi = api;
  166. };
  167. const props = {
  168. getFormApi,
  169. children: <Form.Input trigger="change" field="name" fieldClassName="test" />,
  170. };
  171. const form = getForm(props);
  172. let errorMessage = 'not muji';
  173. formApi.setError('name', errorMessage);
  174. let expectFormState = {
  175. values: {},
  176. errors: { name: errorMessage },
  177. touched: {},
  178. };
  179. expect(formApi.getFormState()).toEqual(expectFormState);
  180. form.update();
  181. expect(form.find(`.test .semi-form-field-error-message`).text()).toEqual(errorMessage);
  182. });
  183. it('formApi-setTouched', () => {
  184. let formApi = null;
  185. let getFormApi = api => {
  186. formApi = api;
  187. };
  188. let props = {
  189. getFormApi,
  190. children: fields,
  191. };
  192. const form = getForm(props);
  193. let event = {};
  194. form.find(`.semi-input`).simulate('blur', event);
  195. expect(formApi.getTouched('name')).toEqual(true);
  196. expect(!formApi.getTouched('business')).toEqual(true);
  197. });
  198. it('formApi-setValue', () => {
  199. let formApi = null;
  200. let getFormApi = api => {
  201. formApi = api;
  202. };
  203. let props = {
  204. getFormApi,
  205. children: fields,
  206. };
  207. let expectVal = 'semi';
  208. const form = getForm(props);
  209. formApi.setValue('name', expectVal);
  210. expect(formApi.getValue('name')).toEqual(expectVal);
  211. expect(form.find(`.semi-input`).instance().value).toEqual(expectVal);
  212. });
  213. it('formApi-reset', () => {
  214. let formApi = null;
  215. const props = {
  216. children: fields,
  217. getFormApi: api => {
  218. formApi = api;
  219. },
  220. initValues: {
  221. name: 'a',
  222. },
  223. };
  224. const form = getForm(props);
  225. let event = { target: { value: 'b' } };
  226. form.find(`.semi-input`).simulate('change', event);
  227. formApi.reset();
  228. expect(form.find(`.semi-input`).instance().value).toEqual('a');
  229. expect(formApi.getFormState()).toEqual({
  230. values: { name: 'a' },
  231. errors: {},
  232. touched: {},
  233. });
  234. });
  235. it('formApi-setValues-override', () => {
  236. let formApi = null;
  237. const props = {
  238. children: fields,
  239. getFormApi: api => {
  240. formApi = api;
  241. },
  242. initValues: {
  243. name: 'a',
  244. extraKeyA: 'uno',
  245. },
  246. };
  247. const form = getForm(props);
  248. let expectVal = {
  249. name: 'semi',
  250. business: 'abc',
  251. extraKeyB: 'Kay tse',
  252. };
  253. formApi.setValues(expectVal, { isOverride: true });
  254. expect(formApi.getValue()).toEqual(expectVal);
  255. });
  256. it('formApi-setValues-merge', () => {
  257. let formApi = null;
  258. let initValues = {
  259. name: 'a',
  260. extraKeyA: 'uno',
  261. };
  262. const props = {
  263. children: fields,
  264. getFormApi: api => {
  265. formApi = api;
  266. },
  267. initValues,
  268. };
  269. const form = getForm(props);
  270. let expectVal = {
  271. name: 'semi',
  272. business: 'abc',
  273. extraKeyB: 'not exist',
  274. };
  275. let mergeVal = { name: 'semi', business: 'abc', extraKeyA: 'uno' };
  276. formApi.setValues(expectVal);
  277. expect(formApi.getValue()).toEqual(mergeVal);
  278. });
  279. it('formApi-validate, validate all field, specail field', async () => {
  280. let fields = (
  281. <>
  282. <Form.Input field="a.b" className='ab' validate={(val) => val ? '' : 'ab-err'} />
  283. <Form.Input field="a.c" className='ac' validate={(val) => val ? '' : 'ac-err'} />
  284. </>
  285. )
  286. let formApi = null;
  287. let getFormApi = api => {
  288. formApi = api;
  289. };
  290. let formProps = {
  291. children: fields,
  292. getFormApi,
  293. };
  294. let form = getForm(formProps);
  295. formApi.validate().then(values=>{}).catch(error=> {});
  296. await sleep(400);
  297. expect(formApi.getFormState().errors).toEqual({ a: { b: 'ab-err', c: 'ac-err'}});
  298. formApi.reset();
  299. formApi.validate(['a.c']).then(values=>{}).catch(error=> {});
  300. await sleep(300);
  301. expect(formApi.getFormState().errors).toEqual({ a: { c: 'ac-err'}});
  302. });
  303. it('formApi-validate, nested field', async () => {
  304. let fields = (
  305. <>
  306. <Form.Input field="a.b" className='ab' validate={(val) => val ? '' : 'ab-err'} />
  307. <Form.Input field="a.c" className='ac' validate={(val) => val ? '' : 'ac-err'} />
  308. <Form.Input field="e" className='e' validate={(val) => val ? '' : 'e-err'} />
  309. </>
  310. )
  311. let formApi = null;
  312. let getFormApi = api => {
  313. formApi = api;
  314. };
  315. let formProps = {
  316. children: fields,
  317. getFormApi,
  318. };
  319. let form = getForm(formProps);
  320. formApi.validate(['a']).then(values=>{}).catch(error=> {});
  321. await sleep(300);
  322. expect(formApi.getFormState().errors).toEqual({ a: { b: 'ab-err', c: 'ac-err' }});
  323. })
  324. it('formApi-setValue, when include nested field', async () => {
  325. let fields = (
  326. <>
  327. <Form.Input field="a.b" className='ab' validate={(val) => val ? '' : 'ab-err'} />
  328. <Form.Input field="a.c" className='ac' validate={(val) => val ? '' : 'ac-err'} />
  329. <Form.Input field="e" className='e' validate={(val) => val ? '' : 'e-err'} />
  330. </>
  331. )
  332. let formApi = null;
  333. let getFormApi = api => {
  334. formApi = api;
  335. };
  336. let formProps = {
  337. children: fields,
  338. getFormApi,
  339. };
  340. let form = getForm(formProps);
  341. formApi.setValue('a', { b: 'semi-b', c: 'semi-c'})
  342. await sleep(300);
  343. expect(formApi.getFormState().values).toEqual({ a: { b: 'semi-b', c: 'semi-c' }});
  344. expect(form.find('.ab .semi-input').instance().value).toEqual('semi-b');
  345. expect(form.find('.ac .semi-input').instance().value).toEqual('semi-c');
  346. expect(form.find('.e .semi-input').instance().value).toEqual('');
  347. });
  348. it('formApi-setEror, when include nested field', async () => {
  349. let fields = (
  350. <>
  351. <Form.Input field="a.b" className='ab' validate={(val) => val ? '' : 'ab-err'} />
  352. <Form.Input field="a.c" className='ac' validate={(val) => val ? '' : 'ac-err'} />
  353. <Form.Input field="e" className='e' validate={(val) => val ? '' : 'e-err'} />
  354. </>
  355. )
  356. let formApi = null;
  357. let getFormApi = api => {
  358. formApi = api;
  359. };
  360. let formProps = {
  361. children: fields,
  362. getFormApi,
  363. };
  364. let form = getForm(formProps);
  365. formApi.setError('a', { b: 'ab-err', c: 'ac-err'});
  366. form.update();
  367. await sleep(500);
  368. expect(formApi.getFormState().errors).toEqual({ a: { b: 'ab-err', c: 'ac-err' }});
  369. expect(form.find('.ab .semi-form-field-error-message span').at(1).text()).toEqual('ab-err');
  370. expect(form.find('.ac .semi-form-field-error-message span').at(1).text()).toEqual('ac-err');
  371. });
  372. it('formApi-setTouched, when include nested field', async () => {
  373. let fields = (
  374. <>
  375. <Form.Input field="a.b" className='ab' validate={(val) => val ? '' : 'ab-err'} />
  376. <Form.Input field="a.c" className='ac' validate={(val) => val ? '' : 'ac-err'} />
  377. <Form.Input field="e" className='e' validate={(val) => val ? '' : 'e-err'} />
  378. </>
  379. )
  380. let formApi = null;
  381. let getFormApi = api => {
  382. formApi = api;
  383. };
  384. let formProps = {
  385. children: fields,
  386. getFormApi,
  387. };
  388. let form = getForm(formProps);
  389. formApi.setTouched('a', { b: true, c: true })
  390. await sleep(300);
  391. expect(formApi.getFormState().touched).toEqual({ a: { b: true, c: true }});
  392. })
  393. // it('formApi-submitForm', () => {
  394. // // submit should call validate first
  395. // });
  396. });