Skip to content

Commit 1075185

Browse files
authored
fix validateFirst (#74)
* update fix * update test case
1 parent e66e11e commit 1075185

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

src/utils/validateUtil.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,16 @@ export function validateRules(
182182

183183
const rulePromises = filledRules.map(rule => validateRule(name, value, rule, options));
184184

185-
const summaryPromise: Promise<string[]> = validateFirst
185+
const summaryPromise: Promise<string[]> = (validateFirst
186186
? finishOnFirstFailed(rulePromises)
187-
: finishOnAllFailed(rulePromises).then((errors: string[]): string[] | Promise<string[]> => {
188-
if (!errors.length) {
189-
return [];
190-
}
187+
: finishOnAllFailed(rulePromises)
188+
).then((errors: string[]): string[] | Promise<string[]> => {
189+
if (!errors.length) {
190+
return [];
191+
}
191192

192-
return Promise.reject<string[]>(errors);
193-
});
193+
return Promise.reject<string[]>(errors);
194+
});
194195

195196
// Internal catch error to avoid console error log.
196197
summaryPromise.catch(e => e);
@@ -207,12 +208,19 @@ async function finishOnAllFailed(rulePromises: Promise<string[]>[]): Promise<str
207208
}
208209

209210
async function finishOnFirstFailed(rulePromises: Promise<string[]>[]): Promise<string[]> {
211+
let count = 0;
212+
210213
return new Promise(resolve => {
211214
rulePromises.forEach(promise => {
212215
promise.then(errors => {
213216
if (errors.length) {
214217
resolve(errors);
215218
}
219+
220+
count += 1;
221+
if (count === rulePromises.length) {
222+
resolve([]);
223+
}
216224
});
217225
});
218226
});

tests/validate.test.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,26 +328,38 @@ describe('Form.Validate', () => {
328328

329329
it('validateFirst', async () => {
330330
let form;
331+
let canEnd = false;
332+
const onFinish = jest.fn();
333+
331334
const wrapper = mount(
332335
<div>
333336
<Form
334337
ref={instance => {
335338
form = instance;
336339
}}
340+
onFinish={onFinish}
337341
>
338342
<InfoField
339343
name="username"
340344
validateFirst
341345
rules={[
342346
// Follow promise will never end
343-
{ validator: () => new Promise(() => null) },
344347
{ required: true },
348+
{
349+
validator: () =>
350+
new Promise(resolve => {
351+
if (canEnd) {
352+
resolve();
353+
}
354+
}),
355+
},
345356
]}
346357
/>
347358
</Form>
348359
</div>,
349360
);
350361

362+
// Not pass
351363
await changeValue(wrapper, '');
352364
matchError(wrapper, true);
353365
expect(form.getFieldError('username')).toEqual(["'username' is required"]);
@@ -357,6 +369,16 @@ describe('Form.Validate', () => {
357369
errors: ["'username' is required"],
358370
},
359371
]);
372+
expect(onFinish).not.toHaveBeenCalled();
373+
374+
// Should pass
375+
canEnd = true;
376+
await changeValue(wrapper, 'test');
377+
wrapper.find('form').simulate('submit');
378+
await timeout();
379+
380+
matchError(wrapper, false);
381+
expect(onFinish).toHaveBeenCalledWith({ username: 'test' });
360382
});
361383
});
362384
/* eslint-enable no-template-curly-in-string */

0 commit comments

Comments
 (0)