From bf17c91b05c7217463421a7468503ec487e0f77d Mon Sep 17 00:00:00 2001 From: Ogura Daiki <8hachibee125@gmail.com> Date: Wed, 21 Feb 2024 10:13:07 +0900 Subject: [PATCH] improve [handleSubmit] to able to handle return value --- src/index.test.tsx | 66 +++++++++++++++++++++++++++++++++++++++++++++- src/index.ts | 30 +++++++++++++-------- 2 files changed, 84 insertions(+), 12 deletions(-) diff --git a/src/index.test.tsx b/src/index.test.tsx index 5f2fb51..9e98104 100644 --- a/src/index.test.tsx +++ b/src/index.test.tsx @@ -90,13 +90,20 @@ test('zod parse value before submit', async () => { } else { expect('should not called').toBe(result.error); } + return Promise.resolve('returns value'); }); const Top = () => { return (
-
); }; @@ -123,6 +130,63 @@ test('zod parse value before submit', async () => { }); }); +test('able to handle parse error on submit', async () => { + const TestFormHook = createTestHook(); + + const INPUT_AGE = 'aaaa'; + const EXPECTED_ISSUE = { + code: 'custom', + message: 'Invalid input', + path: ['age'], + }; + + const handleSubmitTester = TestFormHook.handleSubmit((e) => (result) => { + if (result.success) { + expect('should not succeed').toBe(false); + } else { + expect(result.success).toBe(false); + expect(result.error).toStrictEqual([EXPECTED_ISSUE]); + } + return Promise.resolve('returns value'); + }); + + const Top = () => { + return ( +
+ +
+ ); + }; + + render(); + + const ageInput: HTMLInputElement = screen.getByTestId('age-input'); + await userEvent.type(ageInput, INPUT_AGE); + + await waitFor(() => { + const ageInput: HTMLInputElement = screen.getByTestId('age-input'); + expect(ageInput.value).toBe(INPUT_AGE); + }); + + const submitButton = screen.getByTestId('submit-button'); + await userEvent.click(submitButton); + + await waitFor(() => { + console.log('waiting'); + TestFormHook.api.actions.peek((s) => { + expect(s.value.age).toBe(INPUT_AGE); + expect(s.errors.age).toBe(EXPECTED_ISSUE.message); + }); + }); +}); + test('User is able to re-initialize the form state', async () => { const TestFormHook = createTestHook(); diff --git a/src/index.ts b/src/index.ts index 9b600f9..b54cf6e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -249,13 +249,11 @@ export type Controller = { type FormHook> = { controller: Controller; - handleSubmit: ( + handleSubmit: ( handler: ( e: BaseSyntheticEvent, - ) => ( - val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray}, - ) => void | Promise, - ) => (e: BaseSyntheticEvent) => void; + ) => (val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray}) => R, + ) => (e: BaseSyntheticEvent) => Promise; api: Subscriber, FormControllerBehavior>; } & Controller; @@ -276,12 +274,10 @@ export function createFormHook( handler: ( e: BaseSyntheticEvent, - ) => ( - val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray}, - ) => void | Promise, + ) => (val: {success: true; data: zodInfer; error: undefined} | {success: false; error: ReadonlyArray}) => R, ) => { return (e: BaseSyntheticEvent) => { const eventHandled = handler(e); @@ -292,8 +288,20 @@ export function createFormHook { + store.actions.handleIssues(result.error.issues); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return x; + }) as R; + } else { + store.actions.handleIssues(result.error.issues); + return handled as R; + } }); }; },