Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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