Skip to content

Commit

Permalink
fix(computed-types): nested schema (#425)
Browse files Browse the repository at this point in the history
  • Loading branch information
hlubek authored Jul 7, 2022
1 parent 52a6e07 commit fd1b2a7
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 14 deletions.
9 changes: 9 additions & 0 deletions computed-types/src/__tests__/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { computedTypesResolver } from '..';
const schema = Schema({
username: string.min(2).error('username field is required'),
password: string.min(2).error('password field is required'),
address: Schema({
zipCode: string.min(5).max(5).error('zipCode field is required'),
}),
});

type FormData = Type<typeof schema> & { unusedProperty: string };
Expand All @@ -33,6 +36,11 @@ function TestComponent({ onSubmit }: Props) {
<input {...register('password')} />
{errors.password && <span role="alert">{errors.password.message}</span>}

<input {...register('address.zipCode')} />
{errors.address?.zipCode && (
<span role="alert">{errors.address.zipCode.message}</span>
)}

<button type="submit">submit</button>
</form>
);
Expand All @@ -50,5 +58,6 @@ test("form's validation with computed-types and TypeScript's integration", async

expect(screen.getByText(/username field is required/i)).toBeInTheDocument();
expect(screen.getByText(/password field is required/i)).toBeInTheDocument();
expect(screen.getByText(/zipCode field is required/i)).toBeInTheDocument();
expect(handleSubmit).not.toHaveBeenCalled();
});
14 changes: 14 additions & 0 deletions computed-types/src/__tests__/__fixtures__/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ export const schema = Schema({
name: string.min(4).max(4),
})
.optional(),
address: Schema({
city: string.min(3, 'Is required'),
zipCode: string
.min(5, 'Must be 5 characters long')
.max(5, 'Must be 5 characters long'),
}),
});

export const validData: Type<typeof schema> = {
Expand All @@ -43,13 +49,21 @@ export const validData: Type<typeof schema> = {
name: 'name',
},
],
address: {
city: 'Awesome city',
zipCode: '12345',
},
};

export const invalidData = {
password: '___',
email: '',
birthYear: 'birthYear',
like: [{ id: 'z' }],
address: {
city: '',
zipCode: '123',
},
};

export const fields: Record<InternalFieldName, Field['_f']> = {
Expand Down
25 changes: 22 additions & 3 deletions computed-types/src/__tests__/__snapshots__/computed-types.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
exports[`computedTypesResolver should return a single error from computedTypesResolver when validation fails 1`] = `
Object {
"errors": Object {
"address": Object {
"city": Object {
"message": "Is required",
"ref": undefined,
"type": "ValidationError",
},
"zipCode": Object {
"message": "Must be 5 characters long",
"ref": undefined,
"type": "ValidationError",
},
},
"birthYear": Object {
"message": "Expect value to be \\"number\\"",
"ref": undefined,
Expand All @@ -21,9 +33,16 @@ Object {
"type": "ValidationError",
},
"like": Object {
"message": "Expect value to be \\"string\\"",
"ref": undefined,
"type": "ValidationError",
"id": Object {
"message": "Expect value to be \\"number\\"",
"ref": undefined,
"type": "ValidationError",
},
"name": Object {
"message": "Expect value to be \\"string\\"",
"ref": undefined,
"type": "ValidationError",
},
},
"password": Object {
"message": "One uppercase character",
Expand Down
14 changes: 3 additions & 11 deletions computed-types/src/computed-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,14 @@ import { toNestError, validateFieldsNatively } from '@hookform/resolvers';
import type { ValidationError } from 'computed-types';
import type { Resolver } from './types';

const parseErrorSchema = (
computedTypesError: ValidationError,
parsedErrors: FieldErrors = {},
path = '',
) => {
const parseErrorSchema = (computedTypesError: ValidationError) => {
const parsedErrors: FieldErrors = {};
return (computedTypesError.errors || []).reduce((acc, error) => {
const _currentPath = String(error.path[0]);
const _path = path ? `${path}.${_currentPath}` : _currentPath;

acc[_path] = {
acc[error.path.join('.')] = {
type: error.error.name,
message: error.error.message,
};

parseErrorSchema(error.error, acc, _path);

return acc;
}, parsedErrors);
};
Expand Down

0 comments on commit fd1b2a7

Please sign in to comment.