Skip to content

Commit 8eb37fd

Browse files
committed
support schema skip and only
1 parent f59a659 commit 8eb37fd

File tree

4 files changed

+389
-23
lines changed

4 files changed

+389
-23
lines changed

packages/vest/src/typings/schema.d.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
declare function getFn(fieldName: string): string[];
22
declare function getFn(): { [fieldName: string]: string[] };
33

4-
declare function schema(
5-
enforceSchema: any
6-
): (
7-
data: any
8-
) => {
9-
hasErrors: (fieldName?: string) => boolean;
10-
hasWarnings: (fieldName?: string) => boolean;
11-
getErrors: typeof getFn;
12-
getWarnings: typeof getFn;
13-
tests: {
14-
[key: string]: {
15-
hasErrors: boolean;
16-
hasWarnings: boolean;
17-
warnings: string[];
18-
errors: string[];
4+
interface schema {
5+
(enforceSchema: any, body?: (...args: any[]) => void): (
6+
data: any
7+
) => {
8+
hasErrors: (fieldName?: string) => boolean;
9+
hasWarnings: (fieldName?: string) => boolean;
10+
getErrors: typeof getFn;
11+
getWarnings: typeof getFn;
12+
tests: {
13+
[key: string]: {
14+
hasErrors: boolean;
15+
hasWarnings: boolean;
16+
warnings: string[];
17+
errors: string[];
18+
};
1919
};
2020
};
21-
};
21+
22+
skip: (namespace: string) => void;
23+
only: (namespace: string) => void;
24+
}
2225

2326
export default schema;

packages/vest/src/utilities/__tests__/__snapshots__/schema.test.js.snap

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,209 @@ Object {
126126
},
127127
}
128128
`;
129+
130+
exports[`schema function body schema.only Should only validate included fields 1`] = `
131+
Object {
132+
"a": Object {
133+
"errors": Array [
134+
"\\"a\\" must be a number",
135+
],
136+
"hasErrors": true,
137+
"hasWarnings": false,
138+
"warnings": Array [],
139+
},
140+
}
141+
`;
142+
143+
exports[`schema function body schema.only Should only validate included fields 2`] = `
144+
Object {
145+
"a": Array [
146+
"\\"a\\" must be a number",
147+
],
148+
}
149+
`;
150+
151+
exports[`schema function body schema.skip Should validate all but skipped fields 1`] = `
152+
Object {
153+
"b": Object {
154+
"errors": Array [
155+
"\\"b\\" must be a numeric string",
156+
],
157+
"hasErrors": true,
158+
"hasWarnings": false,
159+
"warnings": Array [],
160+
},
161+
"c": Object {
162+
"errors": Array [
163+
"id must be a string",
164+
],
165+
"hasErrors": true,
166+
"hasWarnings": false,
167+
"warnings": Array [],
168+
},
169+
"c[0]": Object {
170+
"errors": Array [
171+
"id must be a string",
172+
],
173+
"hasErrors": true,
174+
"hasWarnings": false,
175+
"warnings": Array [],
176+
},
177+
"c[0].id": Object {
178+
"errors": Array [],
179+
"hasErrors": true,
180+
"hasWarnings": false,
181+
"warnings": Array [],
182+
},
183+
"c[1]": Object {
184+
"errors": Array [
185+
"id must be a string",
186+
],
187+
"hasErrors": true,
188+
"hasWarnings": false,
189+
"warnings": Array [],
190+
},
191+
"c[1].id": Object {
192+
"errors": Array [],
193+
"hasErrors": true,
194+
"hasWarnings": false,
195+
"warnings": Array [],
196+
},
197+
"c[2]": Object {
198+
"errors": Array [],
199+
"hasErrors": false,
200+
"hasWarnings": false,
201+
"warnings": Array [],
202+
},
203+
"c[2].id": Object {
204+
"errors": Array [],
205+
"hasErrors": false,
206+
"hasWarnings": false,
207+
"warnings": Array [],
208+
},
209+
}
210+
`;
211+
212+
exports[`schema function body schema.skip Should validate all but skipped fields 2`] = `
213+
Object {
214+
"b": Array [
215+
"\\"b\\" must be a numeric string",
216+
],
217+
"c": Array [
218+
"id must be a string",
219+
],
220+
"c[0]": Array [
221+
"id must be a string",
222+
],
223+
"c[0].id": Array [],
224+
"c[1]": Array [
225+
"id must be a string",
226+
],
227+
"c[1].id": Array [],
228+
"c[2]": Array [],
229+
"c[2].id": Array [],
230+
}
231+
`;
232+
233+
exports[`schema function body schema.skip Should validate all but skipped fields 3`] = `
234+
Object {
235+
"a": Object {
236+
"errors": Array [
237+
"\\"a\\" must be a number",
238+
],
239+
"hasErrors": true,
240+
"hasWarnings": false,
241+
"warnings": Array [],
242+
},
243+
"b": Object {
244+
"errors": Array [
245+
"\\"b\\" must be a numeric string",
246+
],
247+
"hasErrors": true,
248+
"hasWarnings": false,
249+
"warnings": Array [],
250+
},
251+
}
252+
`;
253+
254+
exports[`schema function body schema.skip Should validate all but skipped fields 4`] = `
255+
Object {
256+
"a": Array [
257+
"\\"a\\" must be a number",
258+
],
259+
"b": Array [
260+
"\\"b\\" must be a numeric string",
261+
],
262+
}
263+
`;
264+
265+
exports[`schema function body schema.skip Should validate all but skipped fields 5`] = `
266+
Object {
267+
"c": Object {
268+
"errors": Array [
269+
"id must be a string",
270+
],
271+
"hasErrors": true,
272+
"hasWarnings": false,
273+
"warnings": Array [],
274+
},
275+
"c[0]": Object {
276+
"errors": Array [
277+
"id must be a string",
278+
],
279+
"hasErrors": true,
280+
"hasWarnings": false,
281+
"warnings": Array [],
282+
},
283+
"c[0].id": Object {
284+
"errors": Array [],
285+
"hasErrors": true,
286+
"hasWarnings": false,
287+
"warnings": Array [],
288+
},
289+
"c[1]": Object {
290+
"errors": Array [
291+
"id must be a string",
292+
],
293+
"hasErrors": true,
294+
"hasWarnings": false,
295+
"warnings": Array [],
296+
},
297+
"c[1].id": Object {
298+
"errors": Array [],
299+
"hasErrors": true,
300+
"hasWarnings": false,
301+
"warnings": Array [],
302+
},
303+
"c[2]": Object {
304+
"errors": Array [],
305+
"hasErrors": false,
306+
"hasWarnings": false,
307+
"warnings": Array [],
308+
},
309+
"c[2].id": Object {
310+
"errors": Array [],
311+
"hasErrors": false,
312+
"hasWarnings": false,
313+
"warnings": Array [],
314+
},
315+
}
316+
`;
317+
318+
exports[`schema function body schema.skip Should validate all but skipped fields 6`] = `
319+
Object {
320+
"c": Array [
321+
"id must be a string",
322+
],
323+
"c[0]": Array [
324+
"id must be a string",
325+
],
326+
"c[0].id": Array [],
327+
"c[1]": Array [
328+
"id must be a string",
329+
],
330+
"c[1].id": Array [],
331+
"c[2]": Array [],
332+
"c[2].id": Array [],
333+
}
334+
`;

packages/vest/src/utilities/__tests__/schema.test.js

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,123 @@ describe('schema', () => {
104104
});
105105
});
106106

107+
describe('schema function body', () => {
108+
const Shape = enforce.shape({
109+
a: enforce.isNumber().message('"a" must be a number'),
110+
b: enforce.isString().isNumeric().message('"b" must be a numeric string'),
111+
c: enforce.isArrayOf(
112+
enforce.shape({ id: enforce.isString() }).message('id must be a string')
113+
),
114+
});
115+
116+
const data = {
117+
a: 'not_a_number',
118+
b: 22,
119+
c: [{ id: 1 }, { id: 2 }, { id: '3' }],
120+
};
121+
122+
it('passes all arguments to function body', () => {
123+
const body = jest.fn();
124+
125+
const Schema = schema(Shape, body);
126+
Schema(data, 'args1', 'args2', 'etc');
127+
128+
expect(body).toHaveBeenCalledWith(data, 'args1', 'args2', 'etc');
129+
});
130+
131+
describe('schema.skip', () => {
132+
it('Should validate all but skipped fields', () => {
133+
const data = {
134+
a: 'not_a_number',
135+
b: 22,
136+
c: [{ id: 1 }, { id: 2 }, { id: '3' }],
137+
};
138+
{
139+
const Schema = schema(Shape, () => {
140+
schema.skip('a');
141+
});
142+
const result = Schema(data);
143+
expect(result.getErrors('a')).toEqual([]);
144+
expect(result.hasErrors('a')).toBe(false);
145+
expect(result.getErrors('b')).toEqual(['"b" must be a numeric string']);
146+
expect(result.hasErrors('b')).toBe(true);
147+
expect(result.tests).not.toHaveProperty('a');
148+
expect(result.tests.b).toBeDefined();
149+
expect(result.tests.c).toBeDefined();
150+
expect(result.tests['c[0]']).toBeDefined();
151+
expect(result.tests['c[0].id']).toBeDefined();
152+
expect(result.tests['c[1].id']).toBeDefined();
153+
expect(result.tests['c[2].id']).toBeDefined();
154+
expect(result.tests).toMatchSnapshot();
155+
expect(result.getErrors()).toMatchSnapshot();
156+
}
157+
{
158+
const Schema = schema(Shape, () => {
159+
schema.skip('c');
160+
});
161+
const result = Schema(data);
162+
expect(result.getErrors('a')).toEqual(['"a" must be a number']);
163+
expect(result.hasErrors('a')).toBe(true);
164+
expect(result.hasErrors('c')).toBe(false);
165+
expect(result.getErrors('c')).toEqual([]);
166+
expect(result.hasErrors('c[0]')).toBe(false);
167+
expect(result.hasErrors('c[0].id')).toBe(false);
168+
expect(result.tests.a).toBeDefined();
169+
expect(result.tests.b).toBeDefined();
170+
expect(result.tests).not.toHaveProperty('c');
171+
expect(result.tests).not.toHaveProperty('c[0]');
172+
expect(result.tests).not.toHaveProperty('c[1]');
173+
expect(result.tests).not.toHaveProperty('c[2]');
174+
expect(result.tests).not.toHaveProperty('c[0].id');
175+
expect(result.tests).not.toHaveProperty('c[1].id');
176+
expect(result.tests).not.toHaveProperty('c[2].id');
177+
expect(result.tests).toMatchSnapshot();
178+
expect(result.getErrors()).toMatchSnapshot();
179+
}
180+
{
181+
const Schema = schema(Shape, () => {
182+
schema.skip('a');
183+
schema.skip('b');
184+
});
185+
const result = Schema(data);
186+
expect(result.tests.a).not.toBeDefined();
187+
expect(result.tests.b).not.toBeDefined();
188+
expect(result.tests.c).toBeDefined();
189+
expect(result.tests).toMatchSnapshot();
190+
expect(result.getErrors()).toMatchSnapshot();
191+
}
192+
});
193+
});
194+
describe('schema.only', () => {
195+
it('Should only validate included fields', () => {
196+
const data = {
197+
a: 'not_a_number',
198+
b: 22,
199+
c: [{ id: 1 }, { id: 2 }, { id: '3' }],
200+
};
201+
{
202+
const Schema = schema(Shape, () => {
203+
schema.only('a');
204+
});
205+
const result = Schema(data);
206+
expect(result.hasErrors('a')).toBe(true);
207+
expect(result.getErrors('a')).toEqual(['"a" must be a number']);
208+
expect(result.hasErrors('b')).toBe(false);
209+
expect(result.hasErrors('c')).toBe(false);
210+
expect(result.tests.a).toBeDefined();
211+
expect(result.tests.b).not.toBeDefined();
212+
expect(result.tests.c).not.toBeDefined();
213+
expect(result.tests['c[0]']).not.toBeDefined();
214+
expect(result.tests['c[0].id']).not.toBeDefined();
215+
expect(result.tests['c[1].id']).not.toBeDefined();
216+
expect(result.tests['c[2].id']).not.toBeDefined();
217+
expect(result.tests).toMatchSnapshot();
218+
expect(result.getErrors()).toMatchSnapshot();
219+
}
220+
});
221+
});
222+
});
223+
107224
const Name = enforce.loose({
108225
first: enforce.isString().message('First name must be a string'),
109226
last: enforce.isString().warn().message('last name must be a string'),

0 commit comments

Comments
 (0)