Skip to content

Commit

Permalink
fix: fix shape validators recursion even when optional
Browse files Browse the repository at this point in the history
  • Loading branch information
5alidz committed Apr 5, 2021
1 parent 2c0c12a commit 994cef6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 11 deletions.
16 changes: 10 additions & 6 deletions src/createErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,22 @@ export function createErrors<T extends Schema>(schema: T, data: any, eager = fal
return null;
},
list: ({ validator, value }) => {
if (shouldSkipValidation(value, validator)) return null;
// NOTE: because null signals continue recursively
// we return an empty object to skip its children
if (shouldSkipValidation(value, validator)) return {};
if (!Array.isArray(value)) return TYPEERR;
return null;
},
listof: ({ validator, value }) => {
if (shouldSkipValidation(value, validator)) return null;
if (!Array.isArray(value)) return TYPEERR;
record: ({ validator, value }) => {
// NOTE: because null signals continue recursively
// we return an empty object to skip its children
if (shouldSkipValidation(value, validator)) return {};
if (!isPlainObject(value)) return TYPEERR;
return null;
},
record: ({ validator, value }) => {
listof: ({ validator, value }) => {
if (shouldSkipValidation(value, validator)) return null;
if (!isPlainObject(value)) return TYPEERR;
if (!Array.isArray(value)) return TYPEERR;
return null;
},
recordof: ({ validator, value }) => {
Expand Down
38 changes: 33 additions & 5 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,30 @@ const Person = createSchema({
email: _.string({
pattern: [/^[^@]+@[^@]+\.[^@]+$/, 'invalid-email'],
}),
tags: _.listof(_.string(), { optional: true }),
friends: _.recordof(_.record({ name: _.string(), id: _.string() }), { optional: true }),
four_tags: _.list([_.string(), _.string(), _.string(), _.string(), _.list([_.number()])], {
optional: true,
}),
meta: _.record({
id: _.string({ minLength: [1, 'invalid-id'], maxLength: [1000, 'invalid-id'] }),
created: _.number({ is: ['integer', 'timestamp-should-be-intger'] }),
updated: _.number({ optional: true }),
nested: _.record(
{
propA: _.number({ optional: true }),
propB: _.boolean({ optional: true }),
propC: _.string({ optional: true }),
propA: _.number(),
propB: _.boolean(),
propC: _.string(),
},
{ optional: true }
),
}),
});

// type IPerson = ReturnType<typeof Person['produce']>;

describe('validate', () => {
test('test ignores optional', () => {
test('test ignores optional properties when not found', () => {
const errors = Person.validate({
is_verified: true,
name: 'abc',
Expand All @@ -52,11 +59,32 @@ describe('validate', () => {
meta: {
id: '123',
created: Date.now(),
updated: Date.now(),
},
});

expect(errors).toBe(null);
});
test('validates optional properties when found', () => {
const errors = Person.validate({
is_premium: 'hello world',
is_verified: true,
name: 'abc',
age: 42,
email: '[email protected]',
meta: {
id: '123',
created: Date.now(),
updated: new Date().toISOString(),
},
});
expect(errors).toStrictEqual({
is_premium: 'invalid-type',
meta: {
updated: 'invalid-type',
},
});
});

test('emits correct error messages', () => {
const errors = Person.validate(
{
Expand Down

0 comments on commit 994cef6

Please sign in to comment.