isvalid 3.2.2 → 3.2.5

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.
package/lib/formalize.js CHANGED
@@ -187,7 +187,7 @@ const formalizeAny = (schema, options = {}) => {
187
187
 
188
188
  if (typeof (options.transform || {}).pre === 'function') {
189
189
  const transformed = options.transform.pre(key, formalizedSchema[key], { schema: formalizedSchema });
190
- formalizedSchema[key] = typeof transformed !== 'undefined' ? transformed : formalizedSchema[key];
190
+ test = formalizedSchema[key] = typeof transformed !== 'undefined' ? transformed : formalizedSchema[key];
191
191
  }
192
192
 
193
193
  // Ensure validator is of correct type.
@@ -208,7 +208,7 @@ const formalizeAny = (schema, options = {}) => {
208
208
 
209
209
  if (typeof (options.transform || {}).post === 'function') {
210
210
  const transformed = options.transform.post(key, formalizedSchema[key], { schema: formalizedSchema }) || formalizedSchema[key];
211
- formalizedSchema[key] = typeof transformed !== 'undefined' ? transformed : formalizedSchema[key];
211
+ test = formalizedSchema[key] = typeof transformed !== 'undefined' ? transformed : formalizedSchema[key];
212
212
  }
213
213
 
214
214
  }
package/lib/validate.js CHANGED
@@ -26,7 +26,7 @@ const validateObject = async (data, schema, options, keyPath, validatedData) =>
26
26
  keyPath,
27
27
  schema._nonFormalizedSchema,
28
28
  'type',
29
- (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).object || {}).type || 'Is not of type Object.')
29
+ (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).object || {}).type || 'Is not of type object.')
30
30
  );
31
31
  }
32
32
 
@@ -84,7 +84,7 @@ const validateArray = async (data, schema, options, keyPath, validatedData) => {
84
84
  keyPath,
85
85
  schema._nonFormalizedSchema,
86
86
  'type',
87
- (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).array || {}).type || 'Is not of type Array.')
87
+ (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).array || {}).type || 'Is not of type array.')
88
88
  );
89
89
 
90
90
  }
@@ -101,7 +101,7 @@ const validateArray = async (data, schema, options, keyPath, validatedData) => {
101
101
  keyPath,
102
102
  schema._nonFormalizedSchema,
103
103
  'len',
104
- (schema.errors || {}).len || customErrorMessage(((options.errorMessages || {}).array || {}).len || ((len) => `Array length is not within range of '${len}'.`), schema.len)
104
+ (schema.errors || {}).len || customErrorMessage(((options.errorMessages || {}).array || {}).len || ((len) => `Array length is not within range of '${len}'.`), schema._nonFormalizedSchema.len)
105
105
  );
106
106
  }
107
107
 
@@ -127,7 +127,7 @@ const validateString = async (data, schema, options, keyPath) => {
127
127
  keyPath,
128
128
  schema._nonFormalizedSchema,
129
129
  'type',
130
- (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).string || {}).type || 'Is not of type String.')
130
+ (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).string || {}).type || 'Is not of type string.')
131
131
  );
132
132
  }
133
133
 
@@ -141,7 +141,7 @@ const validateString = async (data, schema, options, keyPath) => {
141
141
  keyPath,
142
142
  schema._nonFormalizedSchema,
143
143
  'len',
144
- (schema.errors || {}).len || customErrorMessage(((options.errorMessages || {}).string || {}).len || ((len) => `String length is not within range of ${len}`), schema.len)
144
+ (schema.errors || {}).len || customErrorMessage(((options.errorMessages || {}).string || {}).len || ((len) => `String length is not within range of ${len}`), schema._nonFormalizedSchema.len)
145
145
  );
146
146
  }
147
147
  }
@@ -190,7 +190,7 @@ const validateNumber = async (data, schema, options, keyPath) => {
190
190
  keyPath,
191
191
  schema._nonFormalizedSchema,
192
192
  'type',
193
- (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).number || {}).type || 'Is not of type Number.')
193
+ (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).number || {}).type || 'Is not of type number.')
194
194
  );
195
195
 
196
196
  }
@@ -201,7 +201,7 @@ const validateNumber = async (data, schema, options, keyPath) => {
201
201
  keyPath,
202
202
  schema._nonFormalizedSchema,
203
203
  'range',
204
- (schema.errors || {}).range || customErrorMessage(((options.errorMessages || {}).number || {}).range || ((range) => `Not within range of ${range}.`), schema.range)
204
+ (schema.errors || {}).range || customErrorMessage(((options.errorMessages || {}).number || {}).range || ((range) => `Not within range of ${range}.`), schema._nonFormalizedSchema.range)
205
205
  );
206
206
  }
207
207
  }
@@ -213,18 +213,10 @@ const validateNumber = async (data, schema, options, keyPath) => {
213
213
  throw new ValidationError(
214
214
  keyPath,
215
215
  schema._nonFormalizedSchema,
216
- 'unknownKeys',
216
+ 'float',
217
217
  (schema.errors || {}).float || customErrorMessage(((options.errorMessages || {}).number || {}).float || 'Number must be an integer.'));
218
- case 'round':
219
- data = Math.round(data);
220
- break;
221
- case 'floor':
222
- data = Math.floor(data);
223
- break;
224
- case 'ceil':
225
- data = Math.ceil(data);
226
- break;
227
218
  default:
219
+ data = Math[schema.float](data);
228
220
  break;
229
221
  }
230
222
  }
@@ -245,7 +237,7 @@ const validateBoolean = async (data, schema, options, keyPath) => {
245
237
  keyPath,
246
238
  schema._nonFormalizedSchema,
247
239
  'type',
248
- (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).boolean || {}).type || 'Is not of type Boolean.')
240
+ (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).boolean || {}).type || 'Is not of type boolean.')
249
241
  );
250
242
  }
251
243
 
@@ -264,7 +256,7 @@ const validateDate = async (data, schema, options, keyPath) => {
264
256
  keyPath,
265
257
  schema._nonFormalizedSchema,
266
258
  'type',
267
- (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).date || {}).type || 'Is not of type Date.')
259
+ (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).date || {}).type || 'Is not of type date.')
268
260
  );
269
261
  }
270
262
 
@@ -275,7 +267,7 @@ const validateDate = async (data, schema, options, keyPath) => {
275
267
  keyPath,
276
268
  schema._nonFormalizedSchema,
277
269
  'type',
278
- (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).date || {}).type || 'Is not of type Date.')
270
+ (schema.errors || {}).type || customErrorMessage(((options.errorMessages || {}).date || {}).type || 'Is not of type date.')
279
271
  );
280
272
  }
281
273
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isvalid",
3
- "version": "3.2.2",
3
+ "version": "3.2.5",
4
4
  "description": "Async JSON validation library for node.js.",
5
5
  "main": "./index.js",
6
6
  "keywords": [
package/test/formalize.js CHANGED
@@ -185,7 +185,7 @@ describe('schema', function() {
185
185
  it ('should throw error if plugin validator fails formalizing.', () => {
186
186
  expect(f({ type: String, ensureCase: 'not-supported' }))
187
187
  .to.throw(SchemaError)
188
- .with.property('message', 'Only case types: `camel`, `domain`, `http`, `kebab`, `lower`, `pascal`, `snake`, `title`, `upper` are supported.');
188
+ .with.property('message', 'Only case types: `camel`, `domain`, `http`, `kebab`, `pascal`, `snake`, `title` are supported.');
189
189
  });
190
190
  });
191
191
  });
package/test/validate.js CHANGED
@@ -19,7 +19,8 @@ const commonTests = {
19
19
  describe('type', function() {
20
20
  it(`should come back with an error if input is not a(n) ${utils.typeName(type)}.`, () => {
21
21
  return expect(isvalid(invalidData, type))
22
- .to.eventually.be.rejectedWith(ValidationError)
22
+ .to.eventually.be.rejectedWith(`Is not of type ${utils.typeName(type)}.`)
23
+ .and.to.be.instanceOf(ValidationError)
23
24
  .and.to.have.property('validator', 'type');
24
25
  });
25
26
  it(`should come back with no error if input is a(n) ${utils.typeName(type)}.`, () => {
@@ -35,8 +36,10 @@ const commonTests = {
35
36
  type: type,
36
37
  errors: {
37
38
  type: 'Type custom error message.'
38
- }
39
- })).to.eventually.be.rejectedWith(ValidationError).and.has.property('message', 'Type custom error message.');
39
+ }}))
40
+ .to.eventually.be.rejectedWith('Type custom error message.')
41
+ .and.to.be.instanceOf(ValidationError)
42
+ .and.has.property('validator', 'type');
40
43
  });
41
44
  });
42
45
  });
@@ -46,8 +49,10 @@ const commonTests = {
46
49
  it('should come back with an error if required and input is undefined.', () => {
47
50
  return expect(isvalid(undefined, {
48
51
  type: type,
49
- required: true
50
- })).to.eventually.be.rejectedWith(ValidationError).and.to.have.property('validator', 'required');
52
+ required: true}))
53
+ .to.eventually.be.rejectedWith('Data is required.')
54
+ .and.to.be.instanceOf(ValidationError)
55
+ .and.to.have.property('validator', 'required');
51
56
  });
52
57
  it('should come back with no error if required and input is present', () => {
53
58
  return expect(isvalid(validData, {
@@ -70,8 +75,10 @@ const commonTests = {
70
75
  required: true,
71
76
  errors: {
72
77
  required: 'Required custom error message.'
73
- }
74
- })).to.eventually.be.rejectedWith(ValidationError).and.has.property('message', 'Required custom error message.');
78
+ }}))
79
+ .to.eventually.be.rejectedWith('Required custom error message.')
80
+ .and.to.be.instanceOf(ValidationError)
81
+ .and.has.property('validator', 'required');
75
82
  });
76
83
  });
77
84
  });
@@ -81,8 +88,10 @@ const commonTests = {
81
88
  it('should come back with an error if required and does not allow null and input is null.', () => {
82
89
  return expect(isvalid(null, {
83
90
  type: type,
84
- required: true
85
- })).to.eventually.be.rejectedWith(ValidationError).and.to.have.property('validator', 'allowNull');
91
+ required: true}))
92
+ .to.eventually.be.rejectedWith('Cannot be null.')
93
+ .and.to.be.instanceOf(ValidationError)
94
+ .and.to.have.property('validator', 'allowNull');
86
95
  });
87
96
  it('should come back with no error if required and allows null and input is null.', () => {
88
97
  return expect(isvalid(null, {
@@ -94,8 +103,10 @@ const commonTests = {
94
103
  it('should prioritize concrete over defaults.', () => {
95
104
  return expect(isvalid(null, {
96
105
  type: type,
97
- allowNull: false
98
- }, { defaults: { allowNull: true }})).to.eventually.be.rejectedWith(ValidationError).and.to.have.property('validator', 'allowNull');
106
+ allowNull: false}, { defaults: { allowNull: true }}))
107
+ .to.eventually.be.rejectedWith('Cannot be null.')
108
+ .and.to.be.instanceOf(ValidationError)
109
+ .and.to.have.property('validator', 'allowNull');
99
110
  });
100
111
  describe('#errors', function() {
101
112
  it('should come back with an error with custom message if required and does not allow null and input is null.', () => {
@@ -104,8 +115,10 @@ const commonTests = {
104
115
  required: true,
105
116
  errors: {
106
117
  allowNull: 'Allow null custom error message.'
107
- }
108
- })).to.eventually.be.rejectedWith(ValidationError).and.has.property('message', 'Allow null custom error message.');
118
+ }}))
119
+ .to.eventually.be.rejectedWith('Allow null custom error message.')
120
+ .and.to.be.instanceOf(ValidationError)
121
+ .and.has.property('validator', 'allowNull');
109
122
  });
110
123
  });
111
124
  });
@@ -150,8 +163,10 @@ const commonTests = {
150
163
  });
151
164
  it('should come back with error if data does not equal.', () => {
152
165
  return expect(isvalid(invalidData, {
153
- equal: validData
154
- })).to.eventually.be.rejectedWith(ValidationError).and.to.have.property('validator', 'equal');
166
+ equal: validData}))
167
+ .to.eventually.be.rejectedWith(`Data does not equal ${validData}.`)
168
+ .and.to.be.instanceOf(ValidationError)
169
+ .and.to.have.property('validator', 'equal');
155
170
  });
156
171
  });
157
172
  },
@@ -176,8 +191,10 @@ const commonTests = {
176
191
  return expect(isvalid('test', {
177
192
  post: function() {
178
193
  throw new Error('an error');
179
- }
180
- })).to.eventually.be.rejectedWith(ValidationError).and.has.property('message', 'an error');
194
+ }}))
195
+ .to.eventually.be.rejectedWith('an error')
196
+ .and.to.be.instanceOf(ValidationError)
197
+ .and.has.property('message', 'an error');
181
198
  });
182
199
  it('should return original object if synchronous function doesn\'t return.', () => {
183
200
  return expect(isvalid('test', {
@@ -191,10 +208,12 @@ const commonTests = {
191
208
  });
192
209
  it('should reformat err if post is specified and returns an error.', () => {
193
210
  return expect(isvalid({}, {
194
- post: function(obj, schema, fn) {
195
- fn(new Error('This is an error'));
196
- }
197
- })).to.eventually.be.rejectedWith(ValidationError).and.has.property('validator', 'post');
211
+ post: async function() {
212
+ throw new Error('an error');
213
+ }}))
214
+ .to.eventually.be.rejectedWith('an error')
215
+ .and.to.be.instanceOf(ValidationError)
216
+ .and.has.property('validator', 'post');
198
217
  });
199
218
  it('should pass on post schema options if specified.', () => {
200
219
  return expect(isvalid({}, {
@@ -272,8 +291,10 @@ const commonTests = {
272
291
  assert(false, 'This post function should not have been called.');
273
292
  return data + 3;
274
293
  }
275
- ]
276
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('validator', 'post');
294
+ ]}))
295
+ .to.eventually.be.rejectedWith('Stop here')
296
+ .and.to.be.instanceOf(ValidationError)
297
+ .and.have.property('validator', 'post');
277
298
  });
278
299
  it('should have the full validated data so far as a parameter', () => {
279
300
  return expect(isvalid({ why: {} }, {
@@ -325,12 +346,14 @@ describe('validate', function() {
325
346
  });
326
347
  it('should come back with error if string is supplied - but not a number.', () => {
327
348
  return expect(isvalid('abc', Number))
328
- .to.eventually.be.rejectedWith(ValidationError)
349
+ .to.eventually.be.rejectedWith('Is not of type number.')
350
+ .and.to.be.instanceOf(ValidationError)
329
351
  .and.to.have.property('validator', 'type');
330
352
  });
331
353
  it('should come back with error if wrong E notation is supplied - but not a number.', () => {
332
354
  return expect(isvalid('12e', Number))
333
- .to.eventually.be.rejectedWith(ValidationError)
355
+ .to.eventually.be.rejectedWith('Is not of type number.')
356
+ .and.to.be.instanceOf(ValidationError)
334
357
  .and.to.have.property('validator', 'type');
335
358
  });
336
359
  it('should come back with no error and validData set to true if input is string with \'True\'.', () => {
@@ -341,7 +364,8 @@ describe('validate', function() {
341
364
  });
342
365
  it('should come back with error and if string is supplied - but not \'true\' or \'false\'.', () => {
343
366
  return expect(isvalid('123', Boolean))
344
- .to.eventually.be.rejectedWith(ValidationError)
367
+ .to.eventually.be.rejectedWith('Is not of type boolean.')
368
+ .and.to.be.instanceOf(ValidationError)
345
369
  .and.to.have.property('validator', 'type');
346
370
  });
347
371
  it('should come back with no error and validData set to a Date if input is string with an ISO date.', () => {
@@ -354,7 +378,8 @@ describe('validate', function() {
354
378
  });
355
379
  it('should come back with error and if string is supplied - but not ISO date.', () => {
356
380
  return expect(isvalid('19/10/14 2:24:42', Date))
357
- .to.eventually.be.rejectedWith(ValidationError)
381
+ .to.eventually.be.rejectedWith('Is not of type date.')
382
+ .and.to.be.instanceOf(ValidationError)
358
383
  .and.to.have.property('validator', 'type');
359
384
  });
360
385
  });
@@ -423,8 +448,10 @@ describe('validate', function() {
423
448
  awesome: true,
424
449
  why: 'it just is!'
425
450
  }, {
426
- awesome: Boolean
427
- })).to.eventually.be.rejectedWith(ValidationError).and.has.property('validator', 'unknownKeys');
451
+ awesome: Boolean}))
452
+ .to.eventually.be.rejectedWith('Unknown key.')
453
+ .and.to.be.instanceOf(ValidationError)
454
+ .and.has.property('validator', 'unknownKeys');
428
455
  });
429
456
  it('should come back with error if there are unknown keys and unknownKeys is set to \'deny\'.', () => {
430
457
  return expect(isvalid({
@@ -435,8 +462,10 @@ describe('validate', function() {
435
462
  unknownKeys: 'deny',
436
463
  schema: {
437
464
  awesome: Boolean
438
- }
439
- })).to.eventually.be.rejectedWith(ValidationError).and.has.property('validator', 'unknownKeys');
465
+ }}))
466
+ .to.eventually.be.rejectedWith('Unknown key.')
467
+ .and.to.be.instanceOf(ValidationError)
468
+ .and.has.property('validator', 'unknownKeys');
440
469
  });
441
470
  it('should come back with keys removed if unknown keys and unknownKeys is set to \'remove\'.', () => {
442
471
  return expect(isvalid({
@@ -458,8 +487,10 @@ describe('validate', function() {
458
487
  type: String,
459
488
  required: true
460
489
  }
461
- }
462
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('keyPath').to.have.members(['myObject', 'myKey']);
490
+ }}))
491
+ .to.eventually.be.rejectedWith('Data is required.')
492
+ .and.to.be.instanceOf(ValidationError)
493
+ .and.have.property('keyPath').to.have.members(['myObject', 'myKey']);
463
494
  });
464
495
  });
465
496
  describe('#errors', function() {
@@ -475,8 +506,10 @@ describe('validate', function() {
475
506
  },
476
507
  errors: {
477
508
  unknownKeys: 'Not allowed.'
478
- }
479
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('message', 'Not allowed.');
509
+ }}))
510
+ .to.eventually.be.rejectedWith('Not allowed.')
511
+ .and.to.be.instanceOf(ValidationError)
512
+ .and.have.property('message', 'Not allowed.');
480
513
  });
481
514
  });
482
515
  });
@@ -509,8 +542,10 @@ describe('validate', function() {
509
542
  type: Array,
510
543
  schema: {
511
544
  type: String,
512
- }
513
- }, { keyPath: 'root'})).to.eventually.be.rejectedWith(ValidationError).and.have.property('keyPath').eql(['root', 0]);
545
+ }}, { keyPath: 'root'}))
546
+ .to.eventually.be.rejectedWith('Is not of type string.')
547
+ .and.to.be.instanceOf(ValidationError)
548
+ .and.have.property('keyPath').eql(['root', 0]);
514
549
  });
515
550
  });
516
551
  describe('len', function() {
@@ -525,8 +560,10 @@ describe('validate', function() {
525
560
  return expect(isvalid([], {
526
561
  type: Array,
527
562
  len: '2-',
528
- schema: {}
529
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('validator', 'len');
563
+ schema: {}}))
564
+ .to.eventually.be.rejectedWith('Array length is not within range of \'2-\'.')
565
+ .and.to.be.instanceOf(ValidationError)
566
+ .and.have.property('validator', 'len');
530
567
  });
531
568
  describe('#errors', function() {
532
569
  it('should come back with error of post message if array length is not within ranges of len.', () => {
@@ -536,8 +573,10 @@ describe('validate', function() {
536
573
  schema: {},
537
574
  errors: {
538
575
  len: 'Not within range.'
539
- }
540
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('message', 'Not within range.');
576
+ }}))
577
+ .to.eventually.be.rejectedWith('Not within range.')
578
+ .and.to.be.instanceOf(ValidationError)
579
+ .and.have.property('validator', 'len');
541
580
  });
542
581
  });
543
582
  });
@@ -550,8 +589,10 @@ describe('validate', function() {
550
589
  }], {
551
590
  type: Array,
552
591
  unique: true,
553
- schema: { awesome: Boolean }
554
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('validator', 'unique');
592
+ schema: { awesome: Boolean }}))
593
+ .to.eventually.be.rejectedWith('Array is not unique.')
594
+ .and.to.be.instanceOf(ValidationError)
595
+ .and.have.property('validator', 'unique');
555
596
  });
556
597
  it('should come back with no error if array of strings is unique.', () => {
557
598
  return expect(isvalid(['This', 'is', 'an', 'array'], {
@@ -572,46 +613,55 @@ describe('validate', function() {
572
613
  schema: { awesome: Boolean },
573
614
  errors: {
574
615
  unique: 'Not a set.'
575
- }
576
- })).to.eventually.be.rejectedWith(ValidationError).and.to.have.property('message', 'Not a set.');
616
+ }}))
617
+ .to.eventually.be.rejectedWith('Not a set.')
618
+ .and.to.be.instanceOf(ValidationError)
619
+ .and.to.have.property('validator', 'unique');
577
620
  });
578
621
  });
579
- describe('autowrap', function() {
580
- it('should come back with non-array wrapped in array', () => {
581
- return expect(isvalid({
582
- test: true
583
- }, {
584
- type: Array,
585
- autowrap: true,
586
- schema: {
587
- test: Boolean
588
- }
589
- })).to.eventually.be.an('array').and.to.have.property(0).and.to.have.property('test', true);
590
- });
591
- it('should come back with type error if autowrap and not matching sub-schema.', () => {
592
- return expect(isvalid({
593
- test: 'Not a boolean'
594
- }, {
595
- type: Array,
596
- autowrap: true,
597
- schema: {
598
- test: Boolean
599
- }
600
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('validator', 'type');
601
- });
602
- it('should come back with type error if no autowrap and matching sub-schema.', () => {
603
- return expect(isvalid({
604
- test: true
605
- }, [{
622
+ });
623
+ describe('autowrap', function() {
624
+ it('should come back with non-array wrapped in array', () => {
625
+ return expect(isvalid({
626
+ test: true
627
+ }, {
628
+ type: Array,
629
+ autowrap: true,
630
+ schema: {
606
631
  test: Boolean
607
- }])).to.eventually.be.rejectedWith(ValidationError).and.have.property('validator', 'type');
608
- });
609
- it('should prioritize concrete over defaults.', () => {
610
- return expect(isvalid(true, {
611
- type: Array,
612
- autowrap: false
613
- }, { defaults: { autowrap: true }})).to.eventually.be.rejectedWith(ValidationError).and.have.property('validator', 'type');
614
- });
632
+ }
633
+ })).to.eventually.be.an('array').and.to.have.property(0).and.to.have.property('test', true);
634
+ });
635
+ it('should come back with type error if autowrap and not matching sub-schema.', () => {
636
+ return expect(isvalid({
637
+ test: 'Not a boolean'
638
+ }, {
639
+ type: Array,
640
+ autowrap: true,
641
+ schema: {
642
+ test: Boolean
643
+ }}))
644
+ .to.eventually.be.rejectedWith('Is not of type boolean.')
645
+ .and.to.be.instanceOf(ValidationError)
646
+ .and.have.property('validator', 'type');
647
+ });
648
+ it('should come back with type error if no autowrap and matching sub-schema.', () => {
649
+ return expect(isvalid({
650
+ test: true
651
+ }, [{
652
+ test: Boolean}]))
653
+ .to.eventually.be.rejectedWith('Is not of type array.')
654
+ .and.to.be.instanceOf(ValidationError)
655
+ .and.have.property('validator', 'type');
656
+ });
657
+ it('should prioritize concrete over defaults.', () => {
658
+ return expect(isvalid(true, {
659
+ type: Array,
660
+ autowrap: false
661
+ }, { defaults: { autowrap: true }}))
662
+ .to.eventually.be.rejectedWith('Is not of type array.')
663
+ .and.to.be.instanceOf(ValidationError)
664
+ .and.have.property('validator', 'type');
615
665
  });
616
666
  });
617
667
  });
@@ -643,7 +693,8 @@ describe('validate', function() {
643
693
  describe('match', function() {
644
694
  it('should come back with an error if string does not match RegExp.', () => {
645
695
  return expect(isvalid('123', { type: 'string', match: /^[a-z]+$/ }))
646
- .to.eventually.be.rejectedWith(ValidationError)
696
+ .to.eventually.be.rejectedWith('Does not match expression ^[a-z]+$.')
697
+ .and.to.be.instanceOf(ValidationError)
647
698
  .and.to.have.property('validator', 'match');
648
699
  });
649
700
  it('should come back with no error and validData should match input string when match is specified and input matches.', () => {
@@ -657,15 +708,18 @@ describe('validate', function() {
657
708
  match: /^[a-z]+$/,
658
709
  errors: {
659
710
  match: 'Must be a string of letters from a to z.'
660
- }
661
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('message', 'Must be a string of letters from a to z.');
711
+ }}))
712
+ .to.eventually.be.rejectedWith('Must be a string of letters from a to z.')
713
+ .and.to.be.instanceOf(ValidationError)
714
+ .and.have.property('validator', 'match');
662
715
  });
663
716
  });
664
717
  });
665
718
  describe('enum', function() {
666
719
  it('should come back with an error if string is not in enum.', () => {
667
720
  return expect(isvalid('123', { type: 'string', enum: ['this','test'] }))
668
- .to.eventually.be.rejectedWith(ValidationError)
721
+ .to.eventually.be.rejectedWith('Possible values are "this" and "test".')
722
+ .and.to.be.instanceOf(ValidationError)
669
723
  .and.have.property('validator', 'enum');
670
724
  });
671
725
  it('should come back with no error if string is in enum.', () => {
@@ -679,15 +733,18 @@ describe('validate', function() {
679
733
  enum: ['this','is','a','test'],
680
734
  errors: {
681
735
  enum: 'Must be a word from the sentence "this is a test".'
682
- }
683
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('message', 'Must be a word from the sentence "this is a test".');
736
+ }}))
737
+ .to.eventually.be.rejectedWith('Must be a word from the sentence "this is a test".')
738
+ .and.to.be.instanceOf(ValidationError)
739
+ .and.have.property('validator', 'enum');
684
740
  });
685
741
  });
686
742
  });
687
743
  describe('length', function() {
688
744
  it('should come back with an error if string is not with range.', () => {
689
745
  return expect(isvalid('123', { type: 'string', len: '-2'}))
690
- .to.eventually.be.rejectedWith(ValidationError)
746
+ .to.eventually.be.rejectedWith('String length is not within range of -2')
747
+ .and.to.be.instanceOf(ValidationError)
691
748
  .and.have.property('validator', 'len');
692
749
  });
693
750
  it('should come back with no error if string is within range.', () => {
@@ -700,8 +757,10 @@ describe('validate', function() {
700
757
  it ('should come back with a custom error message', () => {
701
758
  return expect(isvalid('123', {
702
759
  type: 'string',
703
- len: ['-2', 'My custom error'],
704
- })).to.eventually.be.rejectedWith(ValidationError).and.have.property('message', 'My custom error');
760
+ len: ['-2', 'My custom error']}))
761
+ .to.eventually.be.rejectedWith('My custom error')
762
+ .and.to.be.instanceOf(ValidationError)
763
+ .and.have.property('validator', 'len');
705
764
  });
706
765
  });
707
766
  });
@@ -712,25 +771,11 @@ describe('validate', function() {
712
771
  return expect(isvalid(123, Number))
713
772
  .to.eventually.equal(123);
714
773
  });
715
- it('should throw error if non-integers are not allowed.', () => {
716
- expect(isvalid(2.2, { type: Number, float: 'deny' })).to.eventually.throw(ValidationError);
717
- });
718
- it ('should come back with non-integer values if they are allowed.', () => {
719
- expect(isvalid(2.2, { type: Number })).to.eventually.equal(2.2);
720
- });
721
- it ('should come back with number rounded if `float` is set to `round`.', () => {
722
- expect(isvalid(2.5, { type: Number, float: 'round' })).to.eventually.equal(3);
723
- });
724
- it ('should come back with number ceiled if `float` is set to `ceil`.', () => {
725
- expect(isvalid(2.2, { type: Number, float: 'ceil' })).to.eventually.equal(3);
726
- });
727
- it ('should come back with number floored if `float` is set to `floor`.', () => {
728
- expect(isvalid(2.8, { type: Number, float: 'ceil' })).to.eventually.equal(2);
729
- });
730
774
  describe('range', function() {
731
775
  it('should come back with error if input is not within range.', () => {
732
776
  return expect(isvalid(1, { type: Number, range: '2-4' }))
733
- .to.eventually.be.rejectedWith(ValidationError)
777
+ .to.eventually.be.rejectedWith('Not within')
778
+ .and.to.be.instanceOf(ValidationError)
734
779
  .and.to.have.property('validator', 'range');
735
780
  });
736
781
  it('should come back with no error and output same as input if within range.', () => {
@@ -744,14 +789,36 @@ describe('validate', function() {
744
789
  range: '2-4',
745
790
  errors: {
746
791
  range: 'Must be between 2 and 4.'
747
- }
748
- })).to.eventually.be.rejectedWith(ValidationError).and.to.have.property('message', 'Must be between 2 and 4.');
792
+ }}))
793
+ .to.eventually.be.rejectedWith('Must be between 2 and 4.')
794
+ .and.to.be.instanceOf(ValidationError)
795
+ .and.to.have.property('validator', 'range');
749
796
  });
750
797
  });
751
798
  });
799
+ describe('float', function() {
800
+ it('should throw error if non-integers are not allowed.', () => {
801
+ return expect(isvalid(2.2, { type: Number, float: 'deny' }))
802
+ .to.eventually.be.rejectedWith('Number must be an integer.')
803
+ .and.to.be.instanceOf(ValidationError)
804
+ .and.have.property('validator', 'float');
805
+ });
806
+ it ('should come back with non-integer values if they are allowed.', () => {
807
+ return expect(isvalid(2.2, { type: Number })).to.eventually.equal(2.2);
808
+ });
809
+ it ('should come back with number rounded if `float` is set to `round`.', () => {
810
+ return expect(isvalid(2.5, { type: Number, float: 'round' })).to.eventually.equal(3);
811
+ });
812
+ it ('should come back with number ceiled if `float` is set to `ceil`.', () => {
813
+ return expect(isvalid(2.2, { type: Number, float: 'ceil' })).to.eventually.equal(3);
814
+ });
815
+ it ('should come back with number floored if `float` is set to `floor`.', () => {
816
+ return expect(isvalid(2.8, { type: Number, float: 'floor' })).to.eventually.equal(2);
817
+ });
818
+ });
752
819
  });
753
820
  describe('date validator', function() {
754
- commonTests.all('date', new Date(), 123);
821
+ commonTests.all(Date, new Date(), 123);
755
822
  });
756
823
  describe('other validator', function() {
757
824
  commonTests.all(Test, new Test(), 123);
@@ -759,13 +826,15 @@ describe('validate', function() {
759
826
  describe('plugin validators', function() {
760
827
  it ('should throw error if casing does not match.', function() {
761
828
  return expect(isvalid('my-string', { type: String, ensureCase: 'camel' }))
762
- .to.eventually.rejectedWith(ValidationError)
763
- .and.to.have.property('message', 'Is not camel case.');
829
+ .to.eventually.rejectedWith('Is not camel case.')
830
+ .and.to.be.instanceOf(ValidationError)
831
+ .and.to.have.property('validator', 'ensureCase');
764
832
  });
765
833
  it ('should throw error with custom message if casing does not match.', function() {
766
834
  return expect(isvalid('my-string', { type: String, ensureCase: ['camel', 'Something is not right!'] }))
767
- .to.eventually.rejectedWith(ValidationError)
768
- .and.to.have.property('message', 'Something is not right!');
835
+ .to.eventually.rejectedWith('Something is not right!')
836
+ .and.to.be.instanceOf(ValidationError)
837
+ .and.to.have.property('validator', 'ensureCase');
769
838
  });
770
839
  it ('should come back with correct value.', function() {
771
840
  return expect(isvalid('myString', { type: String, ensureCase: 'camel' }))