1
|
|
|
import { Validator } from '../../src/validator'; |
2
|
|
|
import barSchema from '../../src/schemas/bar'; |
3
|
|
|
import carSchema from '../../src/schemas/car'; |
4
|
|
|
import personSchema from '../../src/schemas/person'; |
5
|
|
|
import addressSchema from '../../src/schemas/address'; |
6
|
|
|
import companySchema from '../../src/schemas/company'; |
7
|
|
|
import test1Schema from '../../src/schemas/test1'; |
8
|
|
|
import Test2 from '../../src/schemas/test2'; |
9
|
|
|
|
10
|
|
|
const test2 = new Test2('me'); |
11
|
|
|
|
12
|
|
|
const testCases = [ |
13
|
|
|
{ |
14
|
|
|
description: 'A valid test with a custom type', |
15
|
|
|
input: { |
16
|
|
|
name: 'test', |
17
|
|
|
test: test2, |
18
|
|
|
}, |
19
|
|
|
schema: test1Schema, |
20
|
|
|
expectedValue: true, |
21
|
|
|
expectedErrors: [], |
22
|
|
|
}, |
23
|
|
|
{ |
24
|
|
|
description: 'A valid test with a sub schema', |
25
|
|
|
input: { |
26
|
|
|
name: 'test', |
27
|
|
|
test: test2, |
28
|
|
|
test3: { example: 'ok' }, |
29
|
|
|
}, |
30
|
|
|
schema: test1Schema, |
31
|
|
|
expectedValue: true, |
32
|
|
|
expectedErrors: [], |
33
|
|
|
}, |
34
|
|
|
{ |
35
|
|
|
description: 'A invalid test with a custom type', |
36
|
|
|
input: { |
37
|
|
|
name: 'test', |
38
|
|
|
test: 'test', |
39
|
|
|
}, |
40
|
|
|
schema: test1Schema, |
41
|
|
|
expectedValue: false, |
42
|
|
|
expectedErrors: [['test', Test2]], |
43
|
|
|
}, |
44
|
|
|
{ |
45
|
|
|
description: 'A invalid test with a sub schema', |
46
|
|
|
input: { |
47
|
|
|
name: 'test', |
48
|
|
|
test: test2, |
49
|
|
|
test3: 'test', |
50
|
|
|
}, |
51
|
|
|
schema: test1Schema, |
52
|
|
|
expectedValue: false, |
53
|
|
|
expectedErrors: [['test3?', { example: String }]], |
54
|
|
|
}, |
55
|
|
|
{ |
56
|
|
|
description: 'A invalid test with a field of the sub scherma', |
57
|
|
|
input: { |
58
|
|
|
name: 'test', |
59
|
|
|
test: test2, |
60
|
|
|
test3: { example: 42 }, |
61
|
|
|
}, |
62
|
|
|
schema: test1Schema, |
63
|
|
|
expectedValue: false, |
64
|
|
|
expectedErrors: [['test3?', { example: String }]], |
65
|
|
|
}, |
66
|
|
|
{ |
67
|
|
|
description: 'A test with a mixed field', |
68
|
|
|
input: { |
69
|
|
|
name: 'test', |
70
|
|
|
test: test2, |
71
|
|
|
test4: { example: 42 }, |
72
|
|
|
}, |
73
|
|
|
schema: test1Schema, |
74
|
|
|
expectedValue: true, |
75
|
|
|
expectedErrors: [], |
76
|
|
|
}, |
77
|
|
|
{ |
78
|
|
|
description: 'A test with a mixed field', |
79
|
|
|
input: { |
80
|
|
|
name: 'test', |
81
|
|
|
test: test2, |
82
|
|
|
test4: 42, |
83
|
|
|
}, |
84
|
|
|
schema: test1Schema, |
85
|
|
|
expectedValue: true, |
86
|
|
|
expectedErrors: [], |
87
|
|
|
}, |
88
|
|
|
{ |
89
|
|
|
description: 'A test with an async function', |
90
|
|
|
input: { |
91
|
|
|
name: 'test', |
92
|
|
|
test: test2, |
93
|
|
|
test5: async () => {}, |
94
|
|
|
}, |
95
|
|
|
schema: test1Schema, |
96
|
|
|
expectedValue: true, |
97
|
|
|
expectedErrors: [], |
98
|
|
|
}, |
99
|
|
|
{ |
100
|
|
|
description: 'A test with an invalid async function', |
101
|
|
|
input: { |
102
|
|
|
name: 'test', |
103
|
|
|
test: test2, |
104
|
|
|
test5: () => {}, |
105
|
|
|
}, |
106
|
|
|
schema: test1Schema, |
107
|
|
|
expectedValue: false, |
108
|
|
|
expectedErrors: [['test5?', 'async']], |
109
|
|
|
}, |
110
|
|
|
{ |
111
|
|
|
description: 'A valid bar', |
112
|
|
|
input: { |
113
|
|
|
name: 'Jimmys drinks', |
114
|
|
|
address: 'Somewhere over the rainbow', |
115
|
|
|
drinks: { |
116
|
|
|
beer: ['Straffe Hendrik', 'Rochefort', 'St Bernard'], |
117
|
|
|
}, |
118
|
|
|
}, |
119
|
|
|
schema: barSchema, |
120
|
|
|
expectedValue: true, |
121
|
|
|
expectedErrors: [], |
122
|
|
|
}, |
123
|
|
|
{ |
124
|
|
|
description: 'An invalid bar', |
125
|
|
|
input: { |
126
|
|
|
name: 'Sjonnies', |
127
|
|
|
address: 'Centrum 001', |
128
|
|
|
drinks: [ |
129
|
|
|
// < No object |
130
|
|
|
'Heineken', |
131
|
|
|
], |
132
|
|
|
}, |
133
|
|
|
schema: barSchema, |
134
|
|
|
expectedValue: false, |
135
|
|
|
expectedErrors: [['drinks', 'object']], |
136
|
|
|
}, |
137
|
|
|
{ |
138
|
|
|
description: 'A valid car', |
139
|
|
|
input: { |
140
|
|
|
brand: 'Mazda', |
141
|
|
|
type: 'MX5 NB 1.8', |
142
|
|
|
milage: 199999.99, |
143
|
|
|
extras: ['2001 Special Edition'], |
144
|
|
|
build: () => {}, |
145
|
|
|
}, |
146
|
|
|
schema: carSchema, |
147
|
|
|
expectedValue: true, |
148
|
|
|
expectedErrors: [], |
149
|
|
|
}, |
150
|
|
|
{ |
151
|
|
|
description: 'An invalid car', |
152
|
|
|
input: { |
153
|
|
|
brand: 'BMW', |
154
|
|
|
type: '335', |
155
|
|
|
// No number |
156
|
|
|
milage: '100000', |
157
|
|
|
extras: ['LCI', 'KW Coilovers'], |
158
|
|
|
}, |
159
|
|
|
schema: carSchema, |
160
|
|
|
expectedValue: false, |
161
|
|
|
expectedErrors: [ |
162
|
|
|
['milage', 'number'], |
163
|
|
|
['build', 'function'], |
164
|
|
|
], |
165
|
|
|
}, |
166
|
|
|
{ |
167
|
|
|
description: 'A valid person', |
168
|
|
|
input: { |
169
|
|
|
name: 'James', |
170
|
|
|
age: 25, |
171
|
|
|
birthDay: new Date('1982-12-24'), |
172
|
|
|
siblings: ['Johnnathan'], |
173
|
|
|
metaData: {}, |
174
|
|
|
active: true, |
175
|
|
|
address: { |
176
|
|
|
street: 'Streetname', |
177
|
|
|
number: 1, |
178
|
|
|
postalCode: '1234AB', |
179
|
|
|
city: 'City', |
180
|
|
|
country: 'Somewehere', |
181
|
|
|
}, |
182
|
|
|
companies: [ |
183
|
|
|
{ name: 'Example', website: new URL('https://hckr.news') }, |
184
|
|
|
], |
185
|
|
|
}, |
186
|
|
|
schema: personSchema, |
187
|
|
|
expectedValue: true, |
188
|
|
|
expectedErrors: [], |
189
|
|
|
}, |
190
|
|
|
{ |
191
|
|
|
description: 'An valid person without metaData', |
192
|
|
|
input: { |
193
|
|
|
name: 'James', |
194
|
|
|
age: 25, |
195
|
|
|
birthDay: new Date('1982-12-24'), |
196
|
|
|
siblings: ['Johnnathan'], |
197
|
|
|
active: false, |
198
|
|
|
address: { |
199
|
|
|
street: 'Streetname', |
200
|
|
|
number: 1, |
201
|
|
|
postalCode: '1234AB', |
202
|
|
|
city: 'City', |
203
|
|
|
country: 'Somewehere', |
204
|
|
|
}, |
205
|
|
|
companies: [{ name: 'Example 1' }, { name: 'Example 2' }], |
206
|
|
|
}, |
207
|
|
|
schema: personSchema, |
208
|
|
|
expectedValue: true, |
209
|
|
|
expectedErrors: [], |
210
|
|
|
}, |
211
|
|
|
{ |
212
|
|
|
description: 'An valid person where metaData is null', |
213
|
|
|
input: { |
214
|
|
|
name: 'James', |
215
|
|
|
age: 25, |
216
|
|
|
birthDay: new Date('1982-12-24'), |
217
|
|
|
siblings: ['Johnnathan'], |
218
|
|
|
metaData: null, |
219
|
|
|
active: true, |
220
|
|
|
address: { |
221
|
|
|
street: 'Streetname', |
222
|
|
|
number: 1, |
223
|
|
|
postalCode: '1234AB', |
224
|
|
|
city: 'City', |
225
|
|
|
country: 'Somewehere', |
226
|
|
|
}, |
227
|
|
|
companies: [{ name: 'Example 1' }, { name: 'Example 2' }], |
228
|
|
|
}, |
229
|
|
|
schema: personSchema, |
230
|
|
|
expectedValue: true, |
231
|
|
|
expectedErrors: [], |
232
|
|
|
}, |
233
|
|
|
{ |
234
|
|
|
description: 'An valid person where metaData is undefined', |
235
|
|
|
input: { |
236
|
|
|
name: 'James', |
237
|
|
|
age: 25, |
238
|
|
|
birthDay: new Date('1982-12-24'), |
239
|
|
|
siblings: ['Johnnathan'], |
240
|
|
|
metaData: undefined, |
241
|
|
|
active: true, |
242
|
|
|
address: { |
243
|
|
|
street: 'Streetname', |
244
|
|
|
number: 1, |
245
|
|
|
postalCode: '1234AB', |
246
|
|
|
city: 'City', |
247
|
|
|
country: 'Somewehere', |
248
|
|
|
}, |
249
|
|
|
companies: [{ name: 'Example 1' }, { name: 'Example 2' }], |
250
|
|
|
}, |
251
|
|
|
schema: personSchema, |
252
|
|
|
expectedValue: true, |
253
|
|
|
expectedErrors: [], |
254
|
|
|
}, |
255
|
|
|
{ |
256
|
|
|
description: 'An invalid person', |
257
|
|
|
input: { |
258
|
|
|
name: 'James', |
259
|
|
|
age: 25, |
260
|
|
|
birthDay: new Date('1982-12-24'), |
261
|
|
|
active: true, |
262
|
|
|
}, |
263
|
|
|
schema: personSchema, |
264
|
|
|
expectedValue: false, |
265
|
|
|
expectedErrors: [ |
266
|
|
|
['siblings', Array], |
267
|
|
|
['address', addressSchema], |
268
|
|
|
['companies', companySchema], |
269
|
|
|
], |
270
|
|
|
}, |
271
|
|
|
{ |
272
|
|
|
description: 'An invalid person 2', |
273
|
|
|
input: '', |
274
|
|
|
schema: personSchema, |
275
|
|
|
expectedValue: false, |
276
|
|
|
expectedErrors: [ |
277
|
|
|
['name', String], |
278
|
|
|
['age', Number], |
279
|
|
|
['birthDay', Date], |
280
|
|
|
['siblings', Array], |
281
|
|
|
['metaData?', Object], |
282
|
|
|
['active', Boolean], |
283
|
|
|
['address', addressSchema], |
284
|
|
|
['companies', companySchema], |
285
|
|
|
], |
286
|
|
|
}, |
287
|
|
|
]; |
288
|
|
|
|
289
|
|
|
describe.each(testCases)( |
290
|
|
|
'Validator test', |
291
|
|
|
({ description, input, schema, expectedValue, expectedErrors }) => { |
292
|
|
|
it(description, () => { |
293
|
|
|
const validator = new Validator(schema); |
294
|
|
|
const valid = validator.validate(input); |
295
|
|
|
|
296
|
|
|
expect(valid).toEqual(expectedValue); |
297
|
|
|
expect(validator.errors).toEqual(expectedErrors); |
298
|
|
|
}); |
299
|
|
|
} |
300
|
|
|
); |
301
|
|
|
|
302
|
|
|
const testCaseArrays = [ |
303
|
|
|
{ |
304
|
|
|
description: 'Valid persons array', |
305
|
|
|
input: [ |
306
|
|
|
{ |
307
|
|
|
name: 'James', |
308
|
|
|
age: 25, |
309
|
|
|
birthDay: new Date('1982-12-24'), |
310
|
|
|
siblings: ['Johnnathan'], |
311
|
|
|
active: true, |
312
|
|
|
address: { |
313
|
|
|
street: 'Streetname', |
314
|
|
|
number: 1, |
315
|
|
|
postalCode: '1234AB', |
316
|
|
|
city: 'City', |
317
|
|
|
country: 'Somewehere', |
318
|
|
|
}, |
319
|
|
|
companies: [{ name: 'Example 1' }, { name: 'Example 2' }], |
320
|
|
|
}, |
321
|
|
|
], |
322
|
|
|
schema: personSchema, |
323
|
|
|
expectedValue: true, |
324
|
|
|
}, |
325
|
|
|
{ |
326
|
|
|
description: 'An invalid person', |
327
|
|
|
input: [ |
328
|
|
|
{ |
329
|
|
|
name: 'James', |
330
|
|
|
age: 25, |
331
|
|
|
birthDay: new Date('1982-12-24'), |
332
|
|
|
active: true, |
333
|
|
|
}, |
334
|
|
|
], |
335
|
|
|
schema: personSchema, |
336
|
|
|
expectedValue: false, |
337
|
|
|
}, |
338
|
|
|
{ |
339
|
|
|
description: 'Not all persons are valid', |
340
|
|
|
input: [ |
341
|
|
|
{ |
342
|
|
|
name: 'James', |
343
|
|
|
age: 25, |
344
|
|
|
birthDay: new Date('1982-12-24'), |
345
|
|
|
siblings: ['Johnnathan'], |
346
|
|
|
active: true, |
347
|
|
|
address: { |
348
|
|
|
street: 'Streetname', |
349
|
|
|
number: 1, |
350
|
|
|
postalCode: '1234AB', |
351
|
|
|
city: 'City', |
352
|
|
|
country: 'Somewehere', |
353
|
|
|
}, |
354
|
|
|
companies: [{ name: 'Example 1' }, { name: 'Example 2' }], |
355
|
|
|
}, |
356
|
|
|
{ |
357
|
|
|
name: 'James', |
358
|
|
|
age: 25, |
359
|
|
|
active: true, |
360
|
|
|
}, |
361
|
|
|
], |
362
|
|
|
schema: personSchema, |
363
|
|
|
expectedValue: false, |
364
|
|
|
}, |
365
|
|
|
{ |
366
|
|
|
description: 'Input isnt an array', |
367
|
|
|
input: { |
368
|
|
|
name: 'James', |
369
|
|
|
age: 25, |
370
|
|
|
birthDay: new Date('1982-12-24'), |
371
|
|
|
siblings: ['Johnnathan'], |
372
|
|
|
active: true, |
373
|
|
|
address: { |
374
|
|
|
street: 'Streetname', |
375
|
|
|
number: 1, |
376
|
|
|
postalCode: '1234AB', |
377
|
|
|
city: 'City', |
378
|
|
|
country: 'Somewehere', |
379
|
|
|
}, |
380
|
|
|
companies: [{ name: 'Example 1' }, { name: 'Example 2' }], |
381
|
|
|
}, |
382
|
|
|
schema: personSchema, |
383
|
|
|
expectedValue: false, |
384
|
|
|
}, |
385
|
|
|
{ |
386
|
|
|
description: 'Input is an empty array', |
387
|
|
|
input: [], |
388
|
|
|
schema: personSchema, |
389
|
|
|
expectedValue: false, |
390
|
|
|
}, |
391
|
|
|
]; |
392
|
|
|
|
393
|
|
|
describe.each(testCaseArrays)( |
394
|
|
|
'Validator test with arrays', |
395
|
|
|
({ description, input, schema, expectedValue }) => { |
396
|
|
|
it(description, () => { |
397
|
|
|
const validator = new Validator(schema); |
398
|
|
|
|
399
|
|
|
expect(validator.validateAll(input)).toEqual(expectedValue); |
400
|
|
|
}); |
401
|
|
|
} |
402
|
|
|
); |
403
|
|
|
|