ejv 2.1.1 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.mocharc.json +8 -8
  2. package/CHANGELOG.md +134 -135
  3. package/README-KR.md +597 -597
  4. package/README.md +603 -603
  5. package/build/cjs/constants.js +1 -0
  6. package/build/cjs/constants.js.map +1 -1
  7. package/build/cjs/ejv.js +3 -0
  8. package/build/cjs/ejv.js.map +1 -1
  9. package/build/cjs/tester.js +11 -1
  10. package/build/cjs/tester.js.map +1 -1
  11. package/build/constants.d.ts +1 -0
  12. package/build/esm/constants.js +1 -0
  13. package/build/esm/constants.js.map +1 -1
  14. package/build/esm/ejv.js +4 -1
  15. package/build/esm/ejv.js.map +1 -1
  16. package/build/esm/tester.js +9 -0
  17. package/build/esm/tester.js.map +1 -1
  18. package/build/tester.d.ts +1 -0
  19. package/eslint.config.mjs +66 -59
  20. package/package.json +54 -54
  21. package/scripts/add-js-extensions.ts +59 -59
  22. package/spec/ArrayScheme.ts +1021 -1021
  23. package/spec/CommonScheme.ts +251 -251
  24. package/spec/DateScheme.ts +472 -472
  25. package/spec/NumberScheme.ts +1160 -1160
  26. package/spec/ObjectScheme.ts +499 -499
  27. package/spec/RegExpScheme.ts +112 -112
  28. package/spec/StringScheme.ts +1407 -1336
  29. package/spec/common-test-util.ts +63 -63
  30. package/spec/ejv.spec.ts +235 -235
  31. package/spec/testers.spec.ts +833 -833
  32. package/src/constants.ts +164 -162
  33. package/src/ejv.ts +1751 -1746
  34. package/src/index.ts +14 -14
  35. package/src/interfaces.ts +144 -144
  36. package/src/tester.ts +323 -312
  37. package/src/util.ts +124 -124
  38. package/tsconfig.cjs.json +8 -8
  39. package/tsconfig.esm.json +7 -7
  40. package/tsconfig.json +19 -19
  41. package/tsconfig.scripts.json +14 -14
  42. package/tsconfig.types.json +9 -9
@@ -1,1021 +1,1021 @@
1
- import { describe, it } from 'mocha';
2
- import { expect } from 'chai';
3
-
4
- import { ejv } from '../src/ejv';
5
-
6
- import { EjvError, Scheme } from '../src/interfaces';
7
- import { ERROR_MESSAGE, ERROR_TYPE } from '../src/constants';
8
- import { createErrorMsg } from '../src/util';
9
- import { checkSchemeError, TypeTester, typeTesterArr } from './common-test-util';
10
-
11
-
12
- describe('ArrayScheme', () => {
13
- describe('type', () => {
14
- describe('mismatch', () => {
15
- typeTesterArr
16
- .filter((obj: TypeTester): boolean => obj.type !== 'array')
17
- .forEach((obj: TypeTester): void => {
18
- it(obj.type, () => {
19
- const testObj = {
20
- a: obj.value
21
- };
22
-
23
- const error: EjvError | null = ejv(testObj, [{
24
- key: 'a',
25
- type: 'array'
26
- }]);
27
-
28
- expect(error).to.be.instanceof(EjvError);
29
-
30
- if (!error) {
31
- throw new Error('spec failed');
32
- }
33
-
34
- expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH);
35
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH, {
36
- placeholders: ['array']
37
- }));
38
- expect(error.path).to.be.eql('a');
39
- expect(error.data).to.be.eql(testObj);
40
- expect(error.errorData).to.be.eql(obj.value);
41
- });
42
- });
43
-
44
- it('multiple types', () => {
45
- const value = 'ejv';
46
- const typeArr: string[] = ['boolean', 'array'];
47
-
48
- const testObj = {
49
- a: value
50
- };
51
-
52
- const error: EjvError | null = ejv(testObj, [{
53
- key: 'a',
54
- type: typeArr
55
- }]);
56
-
57
- expect(error).to.be.instanceof(EjvError);
58
-
59
- if (!error) {
60
- throw new Error('spec failed');
61
- }
62
-
63
- expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH_ONE_OF);
64
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH_ONE_OF, {
65
- placeholders: [JSON.stringify(typeArr)]
66
- }));
67
- expect(error.path).to.be.eql('a');
68
- expect(error.data).to.be.eql(testObj);
69
- expect(error.errorData).to.be.eql(value);
70
- });
71
- });
72
-
73
- describe('match', () => {
74
- it('optional', () => {
75
- expect(ejv({
76
- a: undefined
77
- }, [{
78
- key: 'a',
79
- type: 'array',
80
- optional: true
81
- }])).to.be.null;
82
- });
83
-
84
- it('single type', () => {
85
- expect(ejv({
86
- a: [1, 2, 3]
87
- }, [{
88
- key: 'a',
89
- type: 'array'
90
- }])).to.be.null;
91
- });
92
-
93
- it('multiple types', () => {
94
- expect(ejv({
95
- a: [1, 2, 3]
96
- }, [{
97
- key: 'a',
98
- type: ['array', 'number']
99
- }])).to.be.null;
100
- });
101
-
102
- it('multiple types', () => {
103
- expect(ejv({
104
- a: [1, 2, 3]
105
- }, [{
106
- key: 'a',
107
- type: ['number', 'array']
108
- }])).to.be.null;
109
- });
110
- });
111
-
112
- describe('has invalid value', () => {
113
- it('has undefined', () => {
114
- const value = ['a', undefined];
115
- const testObj = {
116
- a: value
117
- };
118
-
119
- const error: EjvError | null = ejv(testObj, [
120
- { key: 'a', type: 'array', items: 'string' }
121
- ]);
122
-
123
- expect(error).to.be.instanceof(EjvError);
124
-
125
- if (!error) {
126
- throw new Error('spec failed');
127
- }
128
-
129
- expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
130
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
131
- placeholders: ['string']
132
- }));
133
- expect(error.path).to.be.eql('a/1');
134
- expect(error.data).to.be.eql(testObj);
135
- expect(error.errorData).to.be.eql(undefined);
136
- });
137
-
138
- it('has undefined, but optional', () => {
139
- const value = ['a', undefined];
140
- const testObj = {
141
- a: value
142
- };
143
-
144
- expect(ejv(testObj, [
145
- {
146
- key: 'a', type: 'array', items: [
147
- { type: 'string', optional: true }
148
- ]
149
- }
150
- ])).to.be.null;
151
- });
152
-
153
- it('has null', () => {
154
- const value = ['a', null];
155
- const testObj = {
156
- a: value
157
- };
158
-
159
- const error: EjvError | null = ejv(testObj, [
160
- { key: 'a', type: 'array', items: 'string' }
161
- ]);
162
-
163
- expect(error).to.be.instanceof(EjvError);
164
-
165
- if (!error) {
166
- throw new Error('spec failed');
167
- }
168
-
169
- expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
170
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
171
- placeholders: ['string']
172
- }));
173
- expect(error.path).to.be.eql('a/1');
174
- expect(error.data).to.be.eql(testObj);
175
- expect(error.errorData).to.be.eql(null);
176
- });
177
-
178
- it('has null, but nullable', () => {
179
- const value = ['a', null];
180
-
181
- expect(ejv({
182
- a: value
183
- }, [
184
- {
185
- key: 'a', type: 'array', items: [
186
- { type: 'string', nullable: true }
187
- ]
188
- }
189
- ])).to.be.null;
190
- });
191
- });
192
- });
193
-
194
- describe('minLength', () => {
195
- describe('check parameter', () => {
196
- const data = {
197
- a: [1, 2, 3]
198
- };
199
-
200
- it('undefined is ok', () => {
201
- expect(ejv(data, [{
202
- key: 'a',
203
- type: 'array',
204
- minLength: undefined
205
- }])).to.be.null;
206
- });
207
-
208
- it('null', () => {
209
- checkSchemeError({
210
- data: data,
211
- errorScheme: {
212
- key: 'a',
213
- type: 'array',
214
- minLength: null as unknown as number
215
- },
216
-
217
- message: createErrorMsg(ERROR_MESSAGE.MIN_LENGTH_SHOULD_BE_INTEGER)
218
- });
219
- });
220
-
221
- it('float number', () => {
222
- checkSchemeError({
223
- data: data,
224
- errorScheme: {
225
- key: 'a',
226
- type: 'array',
227
- minLength: 1.5
228
- },
229
-
230
- message: createErrorMsg(ERROR_MESSAGE.MIN_LENGTH_SHOULD_BE_INTEGER)
231
- });
232
- });
233
-
234
- it('string', () => {
235
- checkSchemeError({
236
- data: data,
237
- errorScheme: {
238
- key: 'a',
239
- type: 'array',
240
- minLength: '1' as unknown as number
241
- },
242
-
243
- message: createErrorMsg(ERROR_MESSAGE.MIN_LENGTH_SHOULD_BE_INTEGER)
244
- });
245
- });
246
- });
247
-
248
- it('fail', () => {
249
- const value = [1, 2, 3];
250
- const testData = {
251
- a: value
252
- };
253
-
254
- const error: EjvError | null = ejv(testData, [{
255
- key: 'a',
256
- type: 'array',
257
- minLength: 4
258
- }]);
259
-
260
- expect(error).to.be.instanceof(EjvError);
261
-
262
- if (!error) {
263
- throw new Error('spec failed');
264
- }
265
-
266
- expect(error.type).to.be.eql(ERROR_TYPE.MIN_LENGTH);
267
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.MIN_LENGTH, {
268
- placeholders: [4]
269
- }));
270
- expect(error.path).to.be.eql('a');
271
- expect(error.data).to.be.deep.equal(testData);
272
- expect(error.errorData).to.be.ordered.members(value);
273
- });
274
-
275
- it('ok', () => {
276
- expect(ejv({
277
- a: [1, 2, 3]
278
- }, [{
279
- key: 'a',
280
- type: 'array',
281
- minLength: 2
282
- }])).to.be.null;
283
-
284
- expect(ejv({
285
- a: [1, 2, 3]
286
- }, [{
287
- key: 'a',
288
- type: 'array',
289
- minLength: 3
290
- }])).to.be.null;
291
- });
292
- });
293
-
294
- describe('maxLength', () => {
295
- describe('check parameter', () => {
296
- const data = {
297
- a: [1, 2, 3]
298
- };
299
-
300
- it('undefined is ok', () => {
301
- expect(ejv(data, [{
302
- key: 'a',
303
- type: 'array',
304
- maxLength: undefined
305
- }])).to.be.null;
306
- });
307
-
308
- it('null', () => {
309
- checkSchemeError({
310
- data: data,
311
- errorScheme: {
312
- key: 'a',
313
- type: 'array',
314
- maxLength: null as unknown as number
315
- },
316
-
317
- message: createErrorMsg(ERROR_MESSAGE.MAX_LENGTH_SHOULD_BE_INTEGER)
318
- });
319
- });
320
-
321
- it('float number', () => {
322
- checkSchemeError({
323
- data: data,
324
- errorScheme: {
325
- key: 'a',
326
- type: 'array',
327
- maxLength: 1.5
328
- },
329
-
330
- message: createErrorMsg(ERROR_MESSAGE.MAX_LENGTH_SHOULD_BE_INTEGER)
331
- });
332
- });
333
-
334
- it('string', () => {
335
- checkSchemeError({
336
- data: data,
337
- errorScheme: {
338
- key: 'a',
339
- type: 'array',
340
- maxLength: '1' as unknown as number
341
- },
342
-
343
- message: createErrorMsg(ERROR_MESSAGE.MAX_LENGTH_SHOULD_BE_INTEGER)
344
- });
345
- });
346
- });
347
-
348
- it('fail', () => {
349
- const value = [1, 2, 3];
350
- const testData = {
351
- a: value
352
- };
353
-
354
- const error: EjvError | null = ejv(testData, [{
355
- key: 'a',
356
- type: 'array',
357
- maxLength: 2
358
- }]);
359
-
360
- expect(error).to.be.instanceof(EjvError);
361
-
362
- if (!error) {
363
- throw new Error('spec failed');
364
- }
365
-
366
- expect(error.type).to.be.eql(ERROR_TYPE.MAX_LENGTH);
367
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.MAX_LENGTH, {
368
- placeholders: [2]
369
- }));
370
- expect(error.path).to.be.eql('a');
371
- expect(error.data).to.be.deep.equal(testData);
372
- expect(error.errorData).to.be.ordered.members(value);
373
- });
374
-
375
- it('ok', () => {
376
- expect(ejv({
377
- a: [1, 2, 3]
378
- }, [{
379
- key: 'a',
380
- type: 'array',
381
- maxLength: 3
382
- }])).to.be.null;
383
-
384
- expect(ejv({
385
- a: [1, 2, 3]
386
- }, [{
387
- key: 'a',
388
- type: 'array',
389
- maxLength: 4
390
- }])).to.be.null;
391
- });
392
- });
393
-
394
- describe('unique', () => {
395
- describe('check parameter', () => {
396
- const data = {
397
- a: [1, 2, 3]
398
- };
399
-
400
- it('undefined is ok', () => {
401
- expect(ejv(data, [{
402
- key: 'a',
403
- type: 'array',
404
- unique: undefined
405
- }])).to.be.null;
406
- });
407
-
408
- it('null', () => {
409
- checkSchemeError({
410
- data: data,
411
- errorScheme: {
412
- key: 'a',
413
- type: 'array',
414
- unique: null as unknown as boolean
415
- },
416
-
417
- message: createErrorMsg(ERROR_MESSAGE.UNIQUE_SHOULD_BE_BOOLEAN)
418
- });
419
- });
420
-
421
- it('not boolean', () => {
422
- checkSchemeError({
423
- data: data,
424
- errorScheme: {
425
- key: 'a',
426
- type: 'array',
427
- unique: 'hello' as unknown as boolean
428
- },
429
-
430
- message: createErrorMsg(ERROR_MESSAGE.UNIQUE_SHOULD_BE_BOOLEAN)
431
- });
432
- });
433
- });
434
-
435
- it('default', () => {
436
- const error: EjvError | null = ejv({
437
- a: [1, 2, 3],
438
- b: [1, 1, 1],
439
- c: ['a', 'a', 'a']
440
- }, [{
441
- key: 'a',
442
- type: 'array'
443
- }, {
444
- key: 'b',
445
- type: 'array'
446
- }, {
447
- key: 'c',
448
- type: 'array',
449
- items: {
450
- type: 'string',
451
- minLength: 1
452
- }
453
- }]);
454
-
455
- expect(error).to.be.null;
456
- });
457
-
458
- it('false', () => {
459
- const error: EjvError | null = ejv({
460
- a: [1, 2, 3],
461
- b: [1, 1, 1],
462
- c: ['a', 'a', 'a']
463
- }, [{
464
- key: 'a',
465
- type: 'array',
466
- unique: false
467
- }, {
468
- key: 'b',
469
- type: 'array',
470
- unique: false
471
- }, {
472
- key: 'c',
473
- type: 'array',
474
- unique: false,
475
- items: {
476
- type: 'string',
477
- minLength: 1
478
- }
479
- }]);
480
-
481
- expect(error).to.be.null;
482
- });
483
-
484
- it('true', () => {
485
- const numberValue = [1, 1, 1];
486
- const numberTestObj = {
487
- a: [1, 2, 3],
488
- b: numberValue
489
- };
490
-
491
- const error: EjvError | null = ejv(numberTestObj, [{
492
- key: 'a',
493
- type: 'array',
494
- unique: true
495
- }, {
496
- key: 'b',
497
- type: 'array',
498
- unique: true
499
- }]);
500
-
501
- expect(error).to.be.instanceof(EjvError);
502
-
503
- if (!error) {
504
- throw new Error('spec failed');
505
- }
506
-
507
- expect(error.type).to.be.eql(ERROR_TYPE.UNIQUE_ITEMS);
508
- expect(error.message).to.be.eql(ERROR_MESSAGE.UNIQUE_ITEMS);
509
- expect(error.path).to.be.eql('b');
510
- expect(error.data).to.be.deep.equal(numberTestObj);
511
- expect(error.errorData).to.be.ordered.members(numberValue);
512
-
513
- const stringValue = ['a', 'a', 'a'];
514
- const stringTestObj = {
515
- a: stringValue
516
- };
517
-
518
- const stringsError: EjvError | null = ejv(stringTestObj, [{
519
- key: 'a',
520
- type: 'array',
521
- unique: true,
522
- items: {
523
- type: 'string',
524
- minLength: 1
525
- }
526
- }]);
527
-
528
- expect(stringsError).to.be.instanceof(EjvError);
529
-
530
- if (!stringsError) {
531
- throw new Error('spec failed');
532
- }
533
-
534
- expect(stringsError.type).to.be.eql(ERROR_TYPE.UNIQUE_ITEMS);
535
- expect(stringsError.message).to.be.eql(ERROR_MESSAGE.UNIQUE_ITEMS);
536
- expect(stringsError.path).to.be.eql('a');
537
- expect(stringsError.data).to.be.deep.equal(stringTestObj);
538
- expect(stringsError.errorData).to.be.ordered.members(stringValue);
539
- });
540
- });
541
-
542
- describe('items', () => {
543
- describe('check parameter', () => {
544
- const data = {
545
- a: [1, 2, 3]
546
- };
547
-
548
- it('undefined is ok', () => {
549
- expect(ejv(data, [{
550
- key: 'a',
551
- type: 'array',
552
- items: undefined
553
- }])).to.be.null;
554
- });
555
-
556
- it('null', () => {
557
- checkSchemeError({
558
- data: data,
559
- errorScheme: {
560
- key: 'a',
561
- type: 'array',
562
- items: null as unknown as string[]
563
- },
564
-
565
- message: createErrorMsg(ERROR_MESSAGE.INVALID_ITEMS_SCHEME, {
566
- placeholders: ['null']
567
- })
568
- });
569
- });
570
- });
571
-
572
- describe('single data type', () => {
573
- describe('check parameter', () => {
574
- it('invalid data type', () => {
575
- const invalidDataType = 'invalidDataType';
576
-
577
- checkSchemeError({
578
- data: {
579
- a: [1, 2, 3]
580
- },
581
- errorScheme: {
582
- key: 'a',
583
- type: 'array',
584
- items: invalidDataType
585
- },
586
-
587
- message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
588
- placeholders: [invalidDataType]
589
- })
590
- });
591
- });
592
- });
593
-
594
- it('fail', () => {
595
- const value = [1, 2, 3];
596
- const testObj = {
597
- a: value
598
- };
599
-
600
- const error: EjvError | null = ejv(testObj, [{
601
- key: 'a',
602
- type: 'array',
603
- items: 'string'
604
- }]);
605
-
606
- expect(error).to.be.instanceof(EjvError);
607
-
608
- if (!error) {
609
- throw new Error('spec failed');
610
- }
611
-
612
- expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
613
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
614
- placeholders: ['string']
615
- }));
616
- expect(error.path).to.be.eql('a/0');
617
- expect(error.data).to.be.deep.equal(testObj);
618
- expect(error.errorData).to.be.eql(value[0]);
619
- });
620
-
621
- it('ok', () => {
622
- expect(ejv({
623
- a: [1, 2, 3]
624
- }, [{
625
- key: 'a',
626
- type: 'array',
627
- items: 'number'
628
- }])).to.be.null;
629
- });
630
-
631
- it('ok - empty array', () => {
632
- const error: EjvError | null = ejv({
633
- a: []
634
- }, [{
635
- key: 'a',
636
- type: 'array',
637
- items: 'object'
638
- }]);
639
-
640
- expect(error).to.be.null;
641
- });
642
- });
643
-
644
- describe('multiple data type', () => {
645
- describe('check parameter', () => {
646
- it('invalid data type', () => {
647
- const invalidDataType = 'invalidDataType';
648
-
649
- checkSchemeError({
650
- data: {
651
- a: [1, 2, 3]
652
- },
653
-
654
- errorScheme: {
655
- key: 'a',
656
- type: 'array',
657
- items: ['number', invalidDataType]
658
- },
659
-
660
- message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
661
- placeholders: [invalidDataType]
662
- })
663
- });
664
- });
665
- });
666
-
667
- it('fail', () => {
668
- const enumArr: string[] = ['boolean', 'string'];
669
-
670
- const value = [1, 2, 2];
671
- const testObj = {
672
- a: [1, 2, 3],
673
- b: [1, 2, 2]
674
- };
675
-
676
- const error: EjvError | null = ejv(testObj, [{
677
- key: 'a',
678
- type: 'array',
679
- items: enumArr
680
- }]);
681
-
682
- expect(error).to.be.instanceof(EjvError);
683
-
684
- if (!error) {
685
- throw new Error('spec failed');
686
- }
687
-
688
- expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
689
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
690
- placeholders: [JSON.stringify(enumArr)]
691
- }));
692
- expect(error.path).to.be.eql('a/0');
693
- expect(error.data).to.be.deep.equal(testObj);
694
- expect(error.errorData).to.be.eql(value[0]);
695
- });
696
-
697
- it('ok', () => {
698
- expect(ejv({
699
- a: [1, 2, 3]
700
- }, [{
701
- key: 'a',
702
- type: 'array',
703
- items: ['string', 'number']
704
- }])).to.be.null;
705
-
706
- expect(ejv({
707
- a: [1, 2, 3]
708
- }, [{
709
- key: 'a',
710
- type: 'array',
711
- items: ['number', 'string']
712
- }])).to.be.null;
713
- });
714
- });
715
-
716
- describe('single scheme', () => {
717
- // single scheme has its original error type & message
718
- describe('check parameter', () => {
719
- it('invalid data type', () => {
720
- const invalidDataType = 'invalidDataType';
721
-
722
- checkSchemeError({
723
- data: {
724
- a: [1, 2, 3]
725
- },
726
- errorScheme: {
727
- key: 'a',
728
- type: 'array',
729
- items: {
730
- type: invalidDataType
731
- } as unknown as Scheme
732
- },
733
-
734
- message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
735
- placeholders: [invalidDataType]
736
- })
737
- });
738
- });
739
- });
740
-
741
- it('fail', () => {
742
- const itemScheme: Scheme = {
743
- type: 'number',
744
- min: 2
745
- };
746
-
747
- const value = [1, 2, 3];
748
- const testObj = {
749
- a: value
750
- };
751
-
752
- const error: EjvError | null = ejv(testObj, [{
753
- key: 'a',
754
- type: 'array',
755
- items: itemScheme
756
- }]);
757
-
758
- expect(error).to.be.instanceof(EjvError);
759
-
760
- if (!error) {
761
- throw new Error('spec failed');
762
- }
763
-
764
- expect(error.type).to.be.eql(ERROR_TYPE.BIGGER_THAN_OR_EQUAL);
765
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.BIGGER_THAN_OR_EQUAL, {
766
- placeholders: [2]
767
- }));
768
- expect(error.path).to.be.eql('a/0');
769
- expect(error.data).to.be.deep.equal(testObj);
770
- expect(error.errorData).to.be.eql(value[0]);
771
- });
772
-
773
- it('ok', () => {
774
- expect(ejv({
775
- a: [1, 2, 3]
776
- }, [{
777
- key: 'a',
778
- type: 'array',
779
- items: {
780
- type: 'number',
781
- min: 1,
782
- max: 3
783
- }
784
- }])).to.be.null;
785
- });
786
-
787
- it('fail - array of object', () => {
788
- const data = {
789
- a: [
790
- { number: 2 },
791
- { number: 3 },
792
- { number: 4 },
793
- { number: 5 }
794
- ]
795
- };
796
-
797
- const error: EjvError | null = ejv(data, [
798
- {
799
- key: 'a', type: 'array', items: [{
800
- type: 'object', properties: [
801
- { key: 'number', type: 'number', min: 4 }
802
- ]
803
- }]
804
- }
805
- ]);
806
-
807
- expect(error).to.be.instanceof(EjvError);
808
-
809
- if (!error) {
810
- throw new Error('spec failed');
811
- }
812
-
813
- expect(error.type).to.be.eql(ERROR_TYPE.BIGGER_THAN_OR_EQUAL);
814
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.BIGGER_THAN_OR_EQUAL, {
815
- placeholders: [4]
816
- }));
817
- expect(error.path).to.be.eql('a/0/number');
818
- expect(error.data).to.be.deep.equal(data);
819
- expect(error.errorData).to.be.eql(2);
820
- });
821
-
822
- it('fail - array of deep object', () => {
823
- const data = {
824
- a: [
825
- { b: { c: { d: { number: 2 } } } },
826
- { b: { c: { d: { number: 3 } } } },
827
- { b: { c: { d: { number: 4 } } } },
828
- { b: { c: { d: { number: 5 } } } }
829
- ]
830
- };
831
-
832
- const error: EjvError | null = ejv(data, [{
833
- key: 'a', type: 'array', items: [{
834
- type: 'object', properties: [{
835
- key: 'b', type: 'object', properties: [{
836
- key: 'c', type: 'object', properties: [{
837
- key: 'd', type: 'object', properties: [
838
- { key: 'number', type: 'number', min: 4 }
839
- ]
840
- }]
841
- }]
842
- }]
843
- }]
844
- }]);
845
-
846
- expect(error).to.be.instanceof(EjvError);
847
-
848
- if (!error) {
849
- throw new Error('spec failed');
850
- }
851
-
852
- expect(error.type).to.be.eql(ERROR_TYPE.BIGGER_THAN_OR_EQUAL);
853
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.BIGGER_THAN_OR_EQUAL, {
854
- placeholders: [4]
855
- }));
856
- expect(error.path).to.be.eql('a/0/b/c/d/number');
857
- expect(error.data).to.be.deep.equal(data);
858
- expect(error.errorData).to.be.eql(2);
859
- });
860
- });
861
-
862
- describe('multiple schemes', () => {
863
- describe('check parameter', () => {
864
- it('invalid data type', () => {
865
- const invalidDataType = 'invalidDataType';
866
-
867
- checkSchemeError({
868
- data: {
869
- a: [1, 2, 3]
870
- },
871
- errorScheme: {
872
- key: 'a',
873
- type: 'array',
874
- items: [{
875
- type: 'invalidDataType'
876
- } as Scheme]
877
- },
878
-
879
- message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
880
- placeholders: [invalidDataType]
881
- })
882
- });
883
- });
884
- });
885
-
886
- it('fail', () => {
887
- const itemScheme1: Scheme = {
888
- type: 'number',
889
- min: 2
890
- };
891
-
892
- const itemScheme2: Scheme = {
893
- type: 'number',
894
- min: 3
895
- };
896
-
897
- const allSchemes: Scheme[] = [itemScheme1, itemScheme2];
898
-
899
- const data = {
900
- a: [1, 2, 3]
901
- };
902
-
903
- const error: EjvError | null = ejv(data, [{
904
- key: 'a',
905
- type: 'array',
906
- items: allSchemes
907
- }]);
908
-
909
- expect(error).to.be.instanceof(EjvError);
910
-
911
- if (!error) {
912
- throw new Error('spec failed');
913
- }
914
-
915
- expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_SCHEMES);
916
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_SCHEMES, {
917
- placeholders: [JSON.stringify(allSchemes)]
918
- }));
919
- expect(error.path).to.be.eql('a/0');
920
- expect(error.data).to.be.deep.equal(data);
921
- expect(error.errorData).to.be.eql(1);
922
- });
923
-
924
- it('ok', () => {
925
- expect(ejv({
926
- a: [1, 2, 3]
927
- }, [{
928
- key: 'a',
929
- type: 'array',
930
- items: [{
931
- type: 'number',
932
- min: 1,
933
- max: 3
934
- }]
935
- }])).to.be.null;
936
-
937
- // multiple schemes
938
- expect(ejv({
939
- a: [1]
940
- }, [{
941
- key: 'a',
942
- type: 'array',
943
- items: [{
944
- type: 'number',
945
- min: 1
946
- }, {
947
- type: 'string'
948
- }]
949
- }])).to.be.null;
950
- });
951
-
952
- it('nested array - single scheme', () => {
953
- const arr: string[] = ['ok', null as unknown as string];
954
- const testObj = {
955
- a: [{
956
- b: arr
957
- }]
958
- };
959
-
960
- const itemScheme: Scheme = { type: 'string', minLength: 1 };
961
-
962
- const error: EjvError | null = ejv(testObj, [{
963
- key: 'a', type: 'array', items: {
964
- type: 'object', properties: [{
965
- key: 'b', type: 'array', unique: true, minLength: 1, optional: true,
966
- items: itemScheme
967
- }]
968
- }
969
- }]);
970
-
971
- expect(error).to.be.instanceof(EjvError);
972
-
973
- if (!error) {
974
- throw new Error('spec failed');
975
- }
976
-
977
- expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH);
978
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH, {
979
- placeholders: [JSON.stringify(itemScheme)]
980
- }));
981
- expect(error.path).to.be.eql('a/0/b/1');
982
- expect(error.data).to.be.eql(testObj);
983
- expect(error.errorData).to.be.eql(null);
984
- });
985
-
986
- it('nested array - multiple chemes', () => {
987
- const arr: string[] = ['ok', null as unknown as string];
988
- const testObj = {
989
- a: [{
990
- b: arr
991
- }]
992
- };
993
-
994
- const itemScheme: Scheme[] = [{ type: 'string', minLength: 1 }];
995
-
996
- const error: EjvError | null = ejv(testObj, [{
997
- key: 'a', type: 'array', items: {
998
- type: 'object', properties: [{
999
- key: 'b', type: 'array', unique: true, minLength: 1, optional: true,
1000
- items: itemScheme
1001
- }]
1002
- }
1003
- }]);
1004
-
1005
- expect(error).to.be.instanceof(EjvError);
1006
-
1007
- if (!error) {
1008
- throw new Error('spec failed');
1009
- }
1010
-
1011
- expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH);
1012
- expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH, {
1013
- placeholders: [JSON.stringify(itemScheme)]
1014
- }));
1015
- expect(error.path).to.be.eql('a/0/b/1');
1016
- expect(error.data).to.be.eql(testObj);
1017
- expect(error.errorData).to.be.eql(null);
1018
- });
1019
- });
1020
- });
1021
- });
1
+ import { describe, it } from 'mocha';
2
+ import { expect } from 'chai';
3
+
4
+ import { ejv } from '../src/ejv';
5
+
6
+ import { EjvError, Scheme } from '../src/interfaces';
7
+ import { ERROR_MESSAGE, ERROR_TYPE } from '../src/constants';
8
+ import { createErrorMsg } from '../src/util';
9
+ import { checkSchemeError, TypeTester, typeTesterArr } from './common-test-util';
10
+
11
+
12
+ describe('ArrayScheme', () => {
13
+ describe('type', () => {
14
+ describe('mismatch', () => {
15
+ typeTesterArr
16
+ .filter((obj: TypeTester): boolean => obj.type !== 'array')
17
+ .forEach((obj: TypeTester): void => {
18
+ it(obj.type, () => {
19
+ const testObj = {
20
+ a: obj.value
21
+ };
22
+
23
+ const error: EjvError | null = ejv(testObj, [{
24
+ key: 'a',
25
+ type: 'array'
26
+ }]);
27
+
28
+ expect(error).to.be.instanceof(EjvError);
29
+
30
+ if (!error) {
31
+ throw new Error('spec failed');
32
+ }
33
+
34
+ expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH);
35
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH, {
36
+ placeholders: ['array']
37
+ }));
38
+ expect(error.path).to.be.eql('a');
39
+ expect(error.data).to.be.eql(testObj);
40
+ expect(error.errorData).to.be.eql(obj.value);
41
+ });
42
+ });
43
+
44
+ it('multiple types', () => {
45
+ const value = 'ejv';
46
+ const typeArr: string[] = ['boolean', 'array'];
47
+
48
+ const testObj = {
49
+ a: value
50
+ };
51
+
52
+ const error: EjvError | null = ejv(testObj, [{
53
+ key: 'a',
54
+ type: typeArr
55
+ }]);
56
+
57
+ expect(error).to.be.instanceof(EjvError);
58
+
59
+ if (!error) {
60
+ throw new Error('spec failed');
61
+ }
62
+
63
+ expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH_ONE_OF);
64
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH_ONE_OF, {
65
+ placeholders: [JSON.stringify(typeArr)]
66
+ }));
67
+ expect(error.path).to.be.eql('a');
68
+ expect(error.data).to.be.eql(testObj);
69
+ expect(error.errorData).to.be.eql(value);
70
+ });
71
+ });
72
+
73
+ describe('match', () => {
74
+ it('optional', () => {
75
+ expect(ejv({
76
+ a: undefined
77
+ }, [{
78
+ key: 'a',
79
+ type: 'array',
80
+ optional: true
81
+ }])).to.be.null;
82
+ });
83
+
84
+ it('single type', () => {
85
+ expect(ejv({
86
+ a: [1, 2, 3]
87
+ }, [{
88
+ key: 'a',
89
+ type: 'array'
90
+ }])).to.be.null;
91
+ });
92
+
93
+ it('multiple types', () => {
94
+ expect(ejv({
95
+ a: [1, 2, 3]
96
+ }, [{
97
+ key: 'a',
98
+ type: ['array', 'number']
99
+ }])).to.be.null;
100
+ });
101
+
102
+ it('multiple types', () => {
103
+ expect(ejv({
104
+ a: [1, 2, 3]
105
+ }, [{
106
+ key: 'a',
107
+ type: ['number', 'array']
108
+ }])).to.be.null;
109
+ });
110
+ });
111
+
112
+ describe('has invalid value', () => {
113
+ it('has undefined', () => {
114
+ const value = ['a', undefined];
115
+ const testObj = {
116
+ a: value
117
+ };
118
+
119
+ const error: EjvError | null = ejv(testObj, [
120
+ { key: 'a', type: 'array', items: 'string' }
121
+ ]);
122
+
123
+ expect(error).to.be.instanceof(EjvError);
124
+
125
+ if (!error) {
126
+ throw new Error('spec failed');
127
+ }
128
+
129
+ expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
130
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
131
+ placeholders: ['string']
132
+ }));
133
+ expect(error.path).to.be.eql('a/1');
134
+ expect(error.data).to.be.eql(testObj);
135
+ expect(error.errorData).to.be.eql(undefined);
136
+ });
137
+
138
+ it('has undefined, but optional', () => {
139
+ const value = ['a', undefined];
140
+ const testObj = {
141
+ a: value
142
+ };
143
+
144
+ expect(ejv(testObj, [
145
+ {
146
+ key: 'a', type: 'array', items: [
147
+ { type: 'string', optional: true }
148
+ ]
149
+ }
150
+ ])).to.be.null;
151
+ });
152
+
153
+ it('has null', () => {
154
+ const value = ['a', null];
155
+ const testObj = {
156
+ a: value
157
+ };
158
+
159
+ const error: EjvError | null = ejv(testObj, [
160
+ { key: 'a', type: 'array', items: 'string' }
161
+ ]);
162
+
163
+ expect(error).to.be.instanceof(EjvError);
164
+
165
+ if (!error) {
166
+ throw new Error('spec failed');
167
+ }
168
+
169
+ expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
170
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
171
+ placeholders: ['string']
172
+ }));
173
+ expect(error.path).to.be.eql('a/1');
174
+ expect(error.data).to.be.eql(testObj);
175
+ expect(error.errorData).to.be.eql(null);
176
+ });
177
+
178
+ it('has null, but nullable', () => {
179
+ const value = ['a', null];
180
+
181
+ expect(ejv({
182
+ a: value
183
+ }, [
184
+ {
185
+ key: 'a', type: 'array', items: [
186
+ { type: 'string', nullable: true }
187
+ ]
188
+ }
189
+ ])).to.be.null;
190
+ });
191
+ });
192
+ });
193
+
194
+ describe('minLength', () => {
195
+ describe('check parameter', () => {
196
+ const data = {
197
+ a: [1, 2, 3]
198
+ };
199
+
200
+ it('undefined is ok', () => {
201
+ expect(ejv(data, [{
202
+ key: 'a',
203
+ type: 'array',
204
+ minLength: undefined
205
+ }])).to.be.null;
206
+ });
207
+
208
+ it('null', () => {
209
+ checkSchemeError({
210
+ data: data,
211
+ errorScheme: {
212
+ key: 'a',
213
+ type: 'array',
214
+ minLength: null as unknown as number
215
+ },
216
+
217
+ message: createErrorMsg(ERROR_MESSAGE.MIN_LENGTH_SHOULD_BE_INTEGER)
218
+ });
219
+ });
220
+
221
+ it('float number', () => {
222
+ checkSchemeError({
223
+ data: data,
224
+ errorScheme: {
225
+ key: 'a',
226
+ type: 'array',
227
+ minLength: 1.5
228
+ },
229
+
230
+ message: createErrorMsg(ERROR_MESSAGE.MIN_LENGTH_SHOULD_BE_INTEGER)
231
+ });
232
+ });
233
+
234
+ it('string', () => {
235
+ checkSchemeError({
236
+ data: data,
237
+ errorScheme: {
238
+ key: 'a',
239
+ type: 'array',
240
+ minLength: '1' as unknown as number
241
+ },
242
+
243
+ message: createErrorMsg(ERROR_MESSAGE.MIN_LENGTH_SHOULD_BE_INTEGER)
244
+ });
245
+ });
246
+ });
247
+
248
+ it('fail', () => {
249
+ const value = [1, 2, 3];
250
+ const testData = {
251
+ a: value
252
+ };
253
+
254
+ const error: EjvError | null = ejv(testData, [{
255
+ key: 'a',
256
+ type: 'array',
257
+ minLength: 4
258
+ }]);
259
+
260
+ expect(error).to.be.instanceof(EjvError);
261
+
262
+ if (!error) {
263
+ throw new Error('spec failed');
264
+ }
265
+
266
+ expect(error.type).to.be.eql(ERROR_TYPE.MIN_LENGTH);
267
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.MIN_LENGTH, {
268
+ placeholders: [4]
269
+ }));
270
+ expect(error.path).to.be.eql('a');
271
+ expect(error.data).to.be.deep.equal(testData);
272
+ expect(error.errorData).to.be.ordered.members(value);
273
+ });
274
+
275
+ it('ok', () => {
276
+ expect(ejv({
277
+ a: [1, 2, 3]
278
+ }, [{
279
+ key: 'a',
280
+ type: 'array',
281
+ minLength: 2
282
+ }])).to.be.null;
283
+
284
+ expect(ejv({
285
+ a: [1, 2, 3]
286
+ }, [{
287
+ key: 'a',
288
+ type: 'array',
289
+ minLength: 3
290
+ }])).to.be.null;
291
+ });
292
+ });
293
+
294
+ describe('maxLength', () => {
295
+ describe('check parameter', () => {
296
+ const data = {
297
+ a: [1, 2, 3]
298
+ };
299
+
300
+ it('undefined is ok', () => {
301
+ expect(ejv(data, [{
302
+ key: 'a',
303
+ type: 'array',
304
+ maxLength: undefined
305
+ }])).to.be.null;
306
+ });
307
+
308
+ it('null', () => {
309
+ checkSchemeError({
310
+ data: data,
311
+ errorScheme: {
312
+ key: 'a',
313
+ type: 'array',
314
+ maxLength: null as unknown as number
315
+ },
316
+
317
+ message: createErrorMsg(ERROR_MESSAGE.MAX_LENGTH_SHOULD_BE_INTEGER)
318
+ });
319
+ });
320
+
321
+ it('float number', () => {
322
+ checkSchemeError({
323
+ data: data,
324
+ errorScheme: {
325
+ key: 'a',
326
+ type: 'array',
327
+ maxLength: 1.5
328
+ },
329
+
330
+ message: createErrorMsg(ERROR_MESSAGE.MAX_LENGTH_SHOULD_BE_INTEGER)
331
+ });
332
+ });
333
+
334
+ it('string', () => {
335
+ checkSchemeError({
336
+ data: data,
337
+ errorScheme: {
338
+ key: 'a',
339
+ type: 'array',
340
+ maxLength: '1' as unknown as number
341
+ },
342
+
343
+ message: createErrorMsg(ERROR_MESSAGE.MAX_LENGTH_SHOULD_BE_INTEGER)
344
+ });
345
+ });
346
+ });
347
+
348
+ it('fail', () => {
349
+ const value = [1, 2, 3];
350
+ const testData = {
351
+ a: value
352
+ };
353
+
354
+ const error: EjvError | null = ejv(testData, [{
355
+ key: 'a',
356
+ type: 'array',
357
+ maxLength: 2
358
+ }]);
359
+
360
+ expect(error).to.be.instanceof(EjvError);
361
+
362
+ if (!error) {
363
+ throw new Error('spec failed');
364
+ }
365
+
366
+ expect(error.type).to.be.eql(ERROR_TYPE.MAX_LENGTH);
367
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.MAX_LENGTH, {
368
+ placeholders: [2]
369
+ }));
370
+ expect(error.path).to.be.eql('a');
371
+ expect(error.data).to.be.deep.equal(testData);
372
+ expect(error.errorData).to.be.ordered.members(value);
373
+ });
374
+
375
+ it('ok', () => {
376
+ expect(ejv({
377
+ a: [1, 2, 3]
378
+ }, [{
379
+ key: 'a',
380
+ type: 'array',
381
+ maxLength: 3
382
+ }])).to.be.null;
383
+
384
+ expect(ejv({
385
+ a: [1, 2, 3]
386
+ }, [{
387
+ key: 'a',
388
+ type: 'array',
389
+ maxLength: 4
390
+ }])).to.be.null;
391
+ });
392
+ });
393
+
394
+ describe('unique', () => {
395
+ describe('check parameter', () => {
396
+ const data = {
397
+ a: [1, 2, 3]
398
+ };
399
+
400
+ it('undefined is ok', () => {
401
+ expect(ejv(data, [{
402
+ key: 'a',
403
+ type: 'array',
404
+ unique: undefined
405
+ }])).to.be.null;
406
+ });
407
+
408
+ it('null', () => {
409
+ checkSchemeError({
410
+ data: data,
411
+ errorScheme: {
412
+ key: 'a',
413
+ type: 'array',
414
+ unique: null as unknown as boolean
415
+ },
416
+
417
+ message: createErrorMsg(ERROR_MESSAGE.UNIQUE_SHOULD_BE_BOOLEAN)
418
+ });
419
+ });
420
+
421
+ it('not boolean', () => {
422
+ checkSchemeError({
423
+ data: data,
424
+ errorScheme: {
425
+ key: 'a',
426
+ type: 'array',
427
+ unique: 'hello' as unknown as boolean
428
+ },
429
+
430
+ message: createErrorMsg(ERROR_MESSAGE.UNIQUE_SHOULD_BE_BOOLEAN)
431
+ });
432
+ });
433
+ });
434
+
435
+ it('default', () => {
436
+ const error: EjvError | null = ejv({
437
+ a: [1, 2, 3],
438
+ b: [1, 1, 1],
439
+ c: ['a', 'a', 'a']
440
+ }, [{
441
+ key: 'a',
442
+ type: 'array'
443
+ }, {
444
+ key: 'b',
445
+ type: 'array'
446
+ }, {
447
+ key: 'c',
448
+ type: 'array',
449
+ items: {
450
+ type: 'string',
451
+ minLength: 1
452
+ }
453
+ }]);
454
+
455
+ expect(error).to.be.null;
456
+ });
457
+
458
+ it('false', () => {
459
+ const error: EjvError | null = ejv({
460
+ a: [1, 2, 3],
461
+ b: [1, 1, 1],
462
+ c: ['a', 'a', 'a']
463
+ }, [{
464
+ key: 'a',
465
+ type: 'array',
466
+ unique: false
467
+ }, {
468
+ key: 'b',
469
+ type: 'array',
470
+ unique: false
471
+ }, {
472
+ key: 'c',
473
+ type: 'array',
474
+ unique: false,
475
+ items: {
476
+ type: 'string',
477
+ minLength: 1
478
+ }
479
+ }]);
480
+
481
+ expect(error).to.be.null;
482
+ });
483
+
484
+ it('true', () => {
485
+ const numberValue = [1, 1, 1];
486
+ const numberTestObj = {
487
+ a: [1, 2, 3],
488
+ b: numberValue
489
+ };
490
+
491
+ const error: EjvError | null = ejv(numberTestObj, [{
492
+ key: 'a',
493
+ type: 'array',
494
+ unique: true
495
+ }, {
496
+ key: 'b',
497
+ type: 'array',
498
+ unique: true
499
+ }]);
500
+
501
+ expect(error).to.be.instanceof(EjvError);
502
+
503
+ if (!error) {
504
+ throw new Error('spec failed');
505
+ }
506
+
507
+ expect(error.type).to.be.eql(ERROR_TYPE.UNIQUE_ITEMS);
508
+ expect(error.message).to.be.eql(ERROR_MESSAGE.UNIQUE_ITEMS);
509
+ expect(error.path).to.be.eql('b');
510
+ expect(error.data).to.be.deep.equal(numberTestObj);
511
+ expect(error.errorData).to.be.ordered.members(numberValue);
512
+
513
+ const stringValue = ['a', 'a', 'a'];
514
+ const stringTestObj = {
515
+ a: stringValue
516
+ };
517
+
518
+ const stringsError: EjvError | null = ejv(stringTestObj, [{
519
+ key: 'a',
520
+ type: 'array',
521
+ unique: true,
522
+ items: {
523
+ type: 'string',
524
+ minLength: 1
525
+ }
526
+ }]);
527
+
528
+ expect(stringsError).to.be.instanceof(EjvError);
529
+
530
+ if (!stringsError) {
531
+ throw new Error('spec failed');
532
+ }
533
+
534
+ expect(stringsError.type).to.be.eql(ERROR_TYPE.UNIQUE_ITEMS);
535
+ expect(stringsError.message).to.be.eql(ERROR_MESSAGE.UNIQUE_ITEMS);
536
+ expect(stringsError.path).to.be.eql('a');
537
+ expect(stringsError.data).to.be.deep.equal(stringTestObj);
538
+ expect(stringsError.errorData).to.be.ordered.members(stringValue);
539
+ });
540
+ });
541
+
542
+ describe('items', () => {
543
+ describe('check parameter', () => {
544
+ const data = {
545
+ a: [1, 2, 3]
546
+ };
547
+
548
+ it('undefined is ok', () => {
549
+ expect(ejv(data, [{
550
+ key: 'a',
551
+ type: 'array',
552
+ items: undefined
553
+ }])).to.be.null;
554
+ });
555
+
556
+ it('null', () => {
557
+ checkSchemeError({
558
+ data: data,
559
+ errorScheme: {
560
+ key: 'a',
561
+ type: 'array',
562
+ items: null as unknown as string[]
563
+ },
564
+
565
+ message: createErrorMsg(ERROR_MESSAGE.INVALID_ITEMS_SCHEME, {
566
+ placeholders: ['null']
567
+ })
568
+ });
569
+ });
570
+ });
571
+
572
+ describe('single data type', () => {
573
+ describe('check parameter', () => {
574
+ it('invalid data type', () => {
575
+ const invalidDataType = 'invalidDataType';
576
+
577
+ checkSchemeError({
578
+ data: {
579
+ a: [1, 2, 3]
580
+ },
581
+ errorScheme: {
582
+ key: 'a',
583
+ type: 'array',
584
+ items: invalidDataType
585
+ },
586
+
587
+ message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
588
+ placeholders: [invalidDataType]
589
+ })
590
+ });
591
+ });
592
+ });
593
+
594
+ it('fail', () => {
595
+ const value = [1, 2, 3];
596
+ const testObj = {
597
+ a: value
598
+ };
599
+
600
+ const error: EjvError | null = ejv(testObj, [{
601
+ key: 'a',
602
+ type: 'array',
603
+ items: 'string'
604
+ }]);
605
+
606
+ expect(error).to.be.instanceof(EjvError);
607
+
608
+ if (!error) {
609
+ throw new Error('spec failed');
610
+ }
611
+
612
+ expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
613
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
614
+ placeholders: ['string']
615
+ }));
616
+ expect(error.path).to.be.eql('a/0');
617
+ expect(error.data).to.be.deep.equal(testObj);
618
+ expect(error.errorData).to.be.eql(value[0]);
619
+ });
620
+
621
+ it('ok', () => {
622
+ expect(ejv({
623
+ a: [1, 2, 3]
624
+ }, [{
625
+ key: 'a',
626
+ type: 'array',
627
+ items: 'number'
628
+ }])).to.be.null;
629
+ });
630
+
631
+ it('ok - empty array', () => {
632
+ const error: EjvError | null = ejv({
633
+ a: []
634
+ }, [{
635
+ key: 'a',
636
+ type: 'array',
637
+ items: 'object'
638
+ }]);
639
+
640
+ expect(error).to.be.null;
641
+ });
642
+ });
643
+
644
+ describe('multiple data type', () => {
645
+ describe('check parameter', () => {
646
+ it('invalid data type', () => {
647
+ const invalidDataType = 'invalidDataType';
648
+
649
+ checkSchemeError({
650
+ data: {
651
+ a: [1, 2, 3]
652
+ },
653
+
654
+ errorScheme: {
655
+ key: 'a',
656
+ type: 'array',
657
+ items: ['number', invalidDataType]
658
+ },
659
+
660
+ message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
661
+ placeholders: [invalidDataType]
662
+ })
663
+ });
664
+ });
665
+ });
666
+
667
+ it('fail', () => {
668
+ const enumArr: string[] = ['boolean', 'string'];
669
+
670
+ const value = [1, 2, 2];
671
+ const testObj = {
672
+ a: [1, 2, 3],
673
+ b: [1, 2, 2]
674
+ };
675
+
676
+ const error: EjvError | null = ejv(testObj, [{
677
+ key: 'a',
678
+ type: 'array',
679
+ items: enumArr
680
+ }]);
681
+
682
+ expect(error).to.be.instanceof(EjvError);
683
+
684
+ if (!error) {
685
+ throw new Error('spec failed');
686
+ }
687
+
688
+ expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_TYPE);
689
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_TYPE, {
690
+ placeholders: [JSON.stringify(enumArr)]
691
+ }));
692
+ expect(error.path).to.be.eql('a/0');
693
+ expect(error.data).to.be.deep.equal(testObj);
694
+ expect(error.errorData).to.be.eql(value[0]);
695
+ });
696
+
697
+ it('ok', () => {
698
+ expect(ejv({
699
+ a: [1, 2, 3]
700
+ }, [{
701
+ key: 'a',
702
+ type: 'array',
703
+ items: ['string', 'number']
704
+ }])).to.be.null;
705
+
706
+ expect(ejv({
707
+ a: [1, 2, 3]
708
+ }, [{
709
+ key: 'a',
710
+ type: 'array',
711
+ items: ['number', 'string']
712
+ }])).to.be.null;
713
+ });
714
+ });
715
+
716
+ describe('single scheme', () => {
717
+ // single scheme has its original error type & message
718
+ describe('check parameter', () => {
719
+ it('invalid data type', () => {
720
+ const invalidDataType = 'invalidDataType';
721
+
722
+ checkSchemeError({
723
+ data: {
724
+ a: [1, 2, 3]
725
+ },
726
+ errorScheme: {
727
+ key: 'a',
728
+ type: 'array',
729
+ items: {
730
+ type: invalidDataType
731
+ } as unknown as Scheme
732
+ },
733
+
734
+ message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
735
+ placeholders: [invalidDataType]
736
+ })
737
+ });
738
+ });
739
+ });
740
+
741
+ it('fail', () => {
742
+ const itemScheme: Scheme = {
743
+ type: 'number',
744
+ min: 2
745
+ };
746
+
747
+ const value = [1, 2, 3];
748
+ const testObj = {
749
+ a: value
750
+ };
751
+
752
+ const error: EjvError | null = ejv(testObj, [{
753
+ key: 'a',
754
+ type: 'array',
755
+ items: itemScheme
756
+ }]);
757
+
758
+ expect(error).to.be.instanceof(EjvError);
759
+
760
+ if (!error) {
761
+ throw new Error('spec failed');
762
+ }
763
+
764
+ expect(error.type).to.be.eql(ERROR_TYPE.BIGGER_THAN_OR_EQUAL);
765
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.BIGGER_THAN_OR_EQUAL, {
766
+ placeholders: [2]
767
+ }));
768
+ expect(error.path).to.be.eql('a/0');
769
+ expect(error.data).to.be.deep.equal(testObj);
770
+ expect(error.errorData).to.be.eql(value[0]);
771
+ });
772
+
773
+ it('ok', () => {
774
+ expect(ejv({
775
+ a: [1, 2, 3]
776
+ }, [{
777
+ key: 'a',
778
+ type: 'array',
779
+ items: {
780
+ type: 'number',
781
+ min: 1,
782
+ max: 3
783
+ }
784
+ }])).to.be.null;
785
+ });
786
+
787
+ it('fail - array of object', () => {
788
+ const data = {
789
+ a: [
790
+ { number: 2 },
791
+ { number: 3 },
792
+ { number: 4 },
793
+ { number: 5 }
794
+ ]
795
+ };
796
+
797
+ const error: EjvError | null = ejv(data, [
798
+ {
799
+ key: 'a', type: 'array', items: [{
800
+ type: 'object', properties: [
801
+ { key: 'number', type: 'number', min: 4 }
802
+ ]
803
+ }]
804
+ }
805
+ ]);
806
+
807
+ expect(error).to.be.instanceof(EjvError);
808
+
809
+ if (!error) {
810
+ throw new Error('spec failed');
811
+ }
812
+
813
+ expect(error.type).to.be.eql(ERROR_TYPE.BIGGER_THAN_OR_EQUAL);
814
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.BIGGER_THAN_OR_EQUAL, {
815
+ placeholders: [4]
816
+ }));
817
+ expect(error.path).to.be.eql('a/0/number');
818
+ expect(error.data).to.be.deep.equal(data);
819
+ expect(error.errorData).to.be.eql(2);
820
+ });
821
+
822
+ it('fail - array of deep object', () => {
823
+ const data = {
824
+ a: [
825
+ { b: { c: { d: { number: 2 } } } },
826
+ { b: { c: { d: { number: 3 } } } },
827
+ { b: { c: { d: { number: 4 } } } },
828
+ { b: { c: { d: { number: 5 } } } }
829
+ ]
830
+ };
831
+
832
+ const error: EjvError | null = ejv(data, [{
833
+ key: 'a', type: 'array', items: [{
834
+ type: 'object', properties: [{
835
+ key: 'b', type: 'object', properties: [{
836
+ key: 'c', type: 'object', properties: [{
837
+ key: 'd', type: 'object', properties: [
838
+ { key: 'number', type: 'number', min: 4 }
839
+ ]
840
+ }]
841
+ }]
842
+ }]
843
+ }]
844
+ }]);
845
+
846
+ expect(error).to.be.instanceof(EjvError);
847
+
848
+ if (!error) {
849
+ throw new Error('spec failed');
850
+ }
851
+
852
+ expect(error.type).to.be.eql(ERROR_TYPE.BIGGER_THAN_OR_EQUAL);
853
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.BIGGER_THAN_OR_EQUAL, {
854
+ placeholders: [4]
855
+ }));
856
+ expect(error.path).to.be.eql('a/0/b/c/d/number');
857
+ expect(error.data).to.be.deep.equal(data);
858
+ expect(error.errorData).to.be.eql(2);
859
+ });
860
+ });
861
+
862
+ describe('multiple schemes', () => {
863
+ describe('check parameter', () => {
864
+ it('invalid data type', () => {
865
+ const invalidDataType = 'invalidDataType';
866
+
867
+ checkSchemeError({
868
+ data: {
869
+ a: [1, 2, 3]
870
+ },
871
+ errorScheme: {
872
+ key: 'a',
873
+ type: 'array',
874
+ items: [{
875
+ type: 'invalidDataType'
876
+ } as Scheme]
877
+ },
878
+
879
+ message: createErrorMsg(ERROR_MESSAGE.SCHEMES_HAS_INVALID_TYPE, {
880
+ placeholders: [invalidDataType]
881
+ })
882
+ });
883
+ });
884
+ });
885
+
886
+ it('fail', () => {
887
+ const itemScheme1: Scheme = {
888
+ type: 'number',
889
+ min: 2
890
+ };
891
+
892
+ const itemScheme2: Scheme = {
893
+ type: 'number',
894
+ min: 3
895
+ };
896
+
897
+ const allSchemes: Scheme[] = [itemScheme1, itemScheme2];
898
+
899
+ const data = {
900
+ a: [1, 2, 3]
901
+ };
902
+
903
+ const error: EjvError | null = ejv(data, [{
904
+ key: 'a',
905
+ type: 'array',
906
+ items: allSchemes
907
+ }]);
908
+
909
+ expect(error).to.be.instanceof(EjvError);
910
+
911
+ if (!error) {
912
+ throw new Error('spec failed');
913
+ }
914
+
915
+ expect(error.type).to.be.eql(ERROR_TYPE.ITEMS_SCHEMES);
916
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.ITEMS_SCHEMES, {
917
+ placeholders: [JSON.stringify(allSchemes)]
918
+ }));
919
+ expect(error.path).to.be.eql('a/0');
920
+ expect(error.data).to.be.deep.equal(data);
921
+ expect(error.errorData).to.be.eql(1);
922
+ });
923
+
924
+ it('ok', () => {
925
+ expect(ejv({
926
+ a: [1, 2, 3]
927
+ }, [{
928
+ key: 'a',
929
+ type: 'array',
930
+ items: [{
931
+ type: 'number',
932
+ min: 1,
933
+ max: 3
934
+ }]
935
+ }])).to.be.null;
936
+
937
+ // multiple schemes
938
+ expect(ejv({
939
+ a: [1]
940
+ }, [{
941
+ key: 'a',
942
+ type: 'array',
943
+ items: [{
944
+ type: 'number',
945
+ min: 1
946
+ }, {
947
+ type: 'string'
948
+ }]
949
+ }])).to.be.null;
950
+ });
951
+
952
+ it('nested array - single scheme', () => {
953
+ const arr: string[] = ['ok', null as unknown as string];
954
+ const testObj = {
955
+ a: [{
956
+ b: arr
957
+ }]
958
+ };
959
+
960
+ const itemScheme: Scheme = { type: 'string', minLength: 1 };
961
+
962
+ const error: EjvError | null = ejv(testObj, [{
963
+ key: 'a', type: 'array', items: {
964
+ type: 'object', properties: [{
965
+ key: 'b', type: 'array', unique: true, minLength: 1, optional: true,
966
+ items: itemScheme
967
+ }]
968
+ }
969
+ }]);
970
+
971
+ expect(error).to.be.instanceof(EjvError);
972
+
973
+ if (!error) {
974
+ throw new Error('spec failed');
975
+ }
976
+
977
+ expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH);
978
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH, {
979
+ placeholders: [JSON.stringify(itemScheme)]
980
+ }));
981
+ expect(error.path).to.be.eql('a/0/b/1');
982
+ expect(error.data).to.be.eql(testObj);
983
+ expect(error.errorData).to.be.eql(null);
984
+ });
985
+
986
+ it('nested array - multiple chemes', () => {
987
+ const arr: string[] = ['ok', null as unknown as string];
988
+ const testObj = {
989
+ a: [{
990
+ b: arr
991
+ }]
992
+ };
993
+
994
+ const itemScheme: Scheme[] = [{ type: 'string', minLength: 1 }];
995
+
996
+ const error: EjvError | null = ejv(testObj, [{
997
+ key: 'a', type: 'array', items: {
998
+ type: 'object', properties: [{
999
+ key: 'b', type: 'array', unique: true, minLength: 1, optional: true,
1000
+ items: itemScheme
1001
+ }]
1002
+ }
1003
+ }]);
1004
+
1005
+ expect(error).to.be.instanceof(EjvError);
1006
+
1007
+ if (!error) {
1008
+ throw new Error('spec failed');
1009
+ }
1010
+
1011
+ expect(error.type).to.be.eql(ERROR_TYPE.TYPE_MISMATCH);
1012
+ expect(error.message).to.be.eql(createErrorMsg(ERROR_MESSAGE.TYPE_MISMATCH, {
1013
+ placeholders: [JSON.stringify(itemScheme)]
1014
+ }));
1015
+ expect(error.path).to.be.eql('a/0/b/1');
1016
+ expect(error.data).to.be.eql(testObj);
1017
+ expect(error.errorData).to.be.eql(null);
1018
+ });
1019
+ });
1020
+ });
1021
+ });