joi 8.4.2 → 9.0.0-0
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/.eslintignore +2 -0
- package/.github/CONTRIBUTING.md +14 -0
- package/.github/ISSUE_TEMPLATE.md +19 -0
- package/.npmignore +21 -0
- package/.travis.yml +8 -0
- package/API.md +1690 -0
- package/README.md +1 -1
- package/examples/conditionalRequire.js +52 -0
- package/examples/customMessage.js +31 -0
- package/examples/multipleWhen.js +26 -0
- package/examples/timestamps.js +22 -0
- package/generate-readme-toc.js +49 -0
- package/images/joi.png +0 -0
- package/images/validation.png +0 -0
- package/lib/any.js +74 -35
- package/lib/array.js +11 -44
- package/lib/boolean.js +9 -2
- package/lib/date.js +0 -3
- package/lib/errors.js +21 -22
- package/lib/index.js +142 -3
- package/lib/language.js +2 -6
- package/lib/object.js +36 -33
- package/lib/string.js +0 -17
- package/package.json +5 -5
- package/test/alternatives.js +490 -0
- package/test/any.js +1751 -0
- package/test/array.js +1049 -0
- package/test/binary.js +190 -0
- package/test/boolean.js +163 -0
- package/test/date.js +441 -0
- package/test/errors.js +512 -0
- package/test/function.js +224 -0
- package/test/helper.js +65 -0
- package/test/index.js +2450 -0
- package/test/number.js +836 -0
- package/test/object.js +1318 -0
- package/test/ref.js +470 -0
- package/test/string.js +3206 -0
- package/lib/lazy.js +0 -51
- package/lib/schemas.js +0 -25
package/test/function.js
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Load modules
|
|
4
|
+
|
|
5
|
+
const Code = require('code');
|
|
6
|
+
const Lab = require('lab');
|
|
7
|
+
const Joi = require('../lib');
|
|
8
|
+
const Helper = require('./helper');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// Declare internals
|
|
12
|
+
|
|
13
|
+
const internals = {};
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
// Test shortcuts
|
|
17
|
+
|
|
18
|
+
const lab = exports.lab = Lab.script();
|
|
19
|
+
const describe = lab.describe;
|
|
20
|
+
const it = lab.it;
|
|
21
|
+
const expect = Code.expect;
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
describe('func', () => {
|
|
25
|
+
|
|
26
|
+
it('validates a function', (done) => {
|
|
27
|
+
|
|
28
|
+
Helper.validate(Joi.func().required(), [
|
|
29
|
+
[function () { }, true],
|
|
30
|
+
['', false, null, '"value" must be a Function']
|
|
31
|
+
], done);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('validates a function arity', (done) => {
|
|
35
|
+
|
|
36
|
+
Helper.validate(Joi.func().arity(2).required(), [
|
|
37
|
+
[function (a,b) { }, true],
|
|
38
|
+
[function (a,b,c) { }, false, null, '"value" must have an arity of 2'],
|
|
39
|
+
[function (a) { }, false, null, '"value" must have an arity of 2'],
|
|
40
|
+
[(a,b) => { }, true],
|
|
41
|
+
[(a,b,c) => { }, false, null, '"value" must have an arity of 2'],
|
|
42
|
+
[(a) => { }, false, null, '"value" must have an arity of 2'],
|
|
43
|
+
['', false, null, '"value" must be a Function']
|
|
44
|
+
], done);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('validates a function arity unless values are illegal', (done) => {
|
|
48
|
+
|
|
49
|
+
const schemaWithStringArity = function (){
|
|
50
|
+
|
|
51
|
+
return Joi.func().arity('deux');
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const schemaWithNegativeArity = function (){
|
|
55
|
+
|
|
56
|
+
return Joi.func().arity(-2);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
expect(schemaWithStringArity).to.throw(Error, 'n must be a positive integer');
|
|
60
|
+
expect(schemaWithNegativeArity).to.throw(Error, 'n must be a positive integer');
|
|
61
|
+
done();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('validates a function min arity', (done) => {
|
|
65
|
+
|
|
66
|
+
Helper.validate(Joi.func().minArity(2).required(), [
|
|
67
|
+
[function (a,b) { }, true],
|
|
68
|
+
[function (a,b,c) { }, true],
|
|
69
|
+
[function (a) { }, false, null, '"value" must have an arity greater or equal to 2'],
|
|
70
|
+
[(a,b) => { }, true],
|
|
71
|
+
[(a,b,c) => { }, true],
|
|
72
|
+
[(a) => { }, false, null, '"value" must have an arity greater or equal to 2'],
|
|
73
|
+
['', false, null, '"value" must be a Function']
|
|
74
|
+
], done);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('validates a function arity unless values are illegal', (done) => {
|
|
78
|
+
|
|
79
|
+
const schemaWithStringMinArity = function (){
|
|
80
|
+
|
|
81
|
+
return Joi.func().minArity('deux');
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const schemaWithNegativeMinArity = function (){
|
|
85
|
+
|
|
86
|
+
return Joi.func().minArity(-2);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const schemaWithZeroArity = function (){
|
|
90
|
+
|
|
91
|
+
return Joi.func().minArity(0);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
expect(schemaWithStringMinArity).to.throw(Error, 'n must be a strict positive integer');
|
|
95
|
+
expect(schemaWithNegativeMinArity).to.throw(Error, 'n must be a strict positive integer');
|
|
96
|
+
expect(schemaWithZeroArity).to.throw(Error, 'n must be a strict positive integer');
|
|
97
|
+
done();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('validates a function max arity', (done) => {
|
|
101
|
+
|
|
102
|
+
Helper.validate(Joi.func().maxArity(2).required(), [
|
|
103
|
+
[function (a,b) { }, true],
|
|
104
|
+
[function (a,b,c) { }, false, null, '"value" must have an arity lesser or equal to 2'],
|
|
105
|
+
[function (a) { }, true],
|
|
106
|
+
[(a,b) => { }, true],
|
|
107
|
+
[(a,b,c) => { }, false, null, '"value" must have an arity lesser or equal to 2'],
|
|
108
|
+
[(a) => { }, true],
|
|
109
|
+
['', false, null, '"value" must be a Function']
|
|
110
|
+
], done);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('validates a function arity unless values are illegal', (done) => {
|
|
114
|
+
|
|
115
|
+
const schemaWithStringMaxArity = function (){
|
|
116
|
+
|
|
117
|
+
return Joi.func().maxArity('deux');
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const schemaWithNegativeMaxArity = function (){
|
|
121
|
+
|
|
122
|
+
return Joi.func().maxArity(-2);
|
|
123
|
+
};
|
|
124
|
+
expect(schemaWithStringMaxArity).to.throw('n must be a positive integer');
|
|
125
|
+
expect(schemaWithNegativeMaxArity).to.throw('n must be a positive integer');
|
|
126
|
+
done();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('validates a function with keys', (done) => {
|
|
130
|
+
|
|
131
|
+
const a = function () { };
|
|
132
|
+
a.a = 'abc';
|
|
133
|
+
|
|
134
|
+
const b = function () { };
|
|
135
|
+
b.a = 123;
|
|
136
|
+
|
|
137
|
+
Helper.validate(Joi.func().keys({ a: Joi.string().required() }).required(), [
|
|
138
|
+
[function () { }, false],
|
|
139
|
+
[a, true],
|
|
140
|
+
[b, false, null, 'child "a" fails because ["a" must be a string]'],
|
|
141
|
+
['', false, null, '"value" must be a Function']
|
|
142
|
+
], done);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('keeps validated value as a function', (done) => {
|
|
146
|
+
|
|
147
|
+
const schema = Joi.func().keys({ a: Joi.number() });
|
|
148
|
+
|
|
149
|
+
const b = 'abc';
|
|
150
|
+
const value = function () {
|
|
151
|
+
|
|
152
|
+
return b;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
value.a = '123';
|
|
156
|
+
|
|
157
|
+
schema.validate(value, (err, validated) => {
|
|
158
|
+
|
|
159
|
+
expect(err).not.to.exist();
|
|
160
|
+
expect(validated).to.be.a.function();
|
|
161
|
+
expect(validated()).to.equal('abc');
|
|
162
|
+
expect(validated).to.not.equal(value);
|
|
163
|
+
done();
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('retains validated value prototype', (done) => {
|
|
168
|
+
|
|
169
|
+
const schema = Joi.func().keys({ a: Joi.number() });
|
|
170
|
+
|
|
171
|
+
const value = function () {
|
|
172
|
+
|
|
173
|
+
this.x = 'o';
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
value.prototype.get = function () {
|
|
177
|
+
|
|
178
|
+
return this.x;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
schema.validate(value, (err, validated) => {
|
|
182
|
+
|
|
183
|
+
expect(err).not.to.exist();
|
|
184
|
+
expect(validated).to.be.a.function();
|
|
185
|
+
const p = new validated();
|
|
186
|
+
expect(p.get()).to.equal('o');
|
|
187
|
+
expect(validated).to.not.equal(value);
|
|
188
|
+
done();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('keeps validated value as a function (no clone)', (done) => {
|
|
193
|
+
|
|
194
|
+
const schema = Joi.func();
|
|
195
|
+
|
|
196
|
+
const b = 'abc';
|
|
197
|
+
const value = function () {
|
|
198
|
+
|
|
199
|
+
return b;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
value.a = '123';
|
|
203
|
+
|
|
204
|
+
schema.validate(value, (err, validated) => {
|
|
205
|
+
|
|
206
|
+
expect(err).not.to.exist();
|
|
207
|
+
expect(validated).to.be.a.function();
|
|
208
|
+
expect(validated()).to.equal('abc');
|
|
209
|
+
expect(validated).to.equal(value);
|
|
210
|
+
done();
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('validates references', (done) => {
|
|
215
|
+
|
|
216
|
+
const schema = Joi.func().ref();
|
|
217
|
+
|
|
218
|
+
Helper.validate(schema, [
|
|
219
|
+
[() => {}, false, null, '"value" must be a Joi reference'],
|
|
220
|
+
[{}, false, null, '"value" must be a Function'],
|
|
221
|
+
[Joi.ref('a.b'), true]
|
|
222
|
+
], done);
|
|
223
|
+
});
|
|
224
|
+
});
|
package/test/helper.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Load modules
|
|
4
|
+
|
|
5
|
+
const Code = require('code');
|
|
6
|
+
const Joi = require('../');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// Declare internals
|
|
10
|
+
|
|
11
|
+
const internals = {};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
// Test shortcuts
|
|
15
|
+
|
|
16
|
+
const expect = Code.expect;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
exports.validate = function (schema, config, callback) {
|
|
20
|
+
|
|
21
|
+
return exports.validateOptions(schema, config, null, callback);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
exports.validateOptions = function (schema, config, options, callback) {
|
|
26
|
+
|
|
27
|
+
const compiled = Joi.compile(schema);
|
|
28
|
+
for (let i = 0; i < config.length; ++i) {
|
|
29
|
+
|
|
30
|
+
const item = config[i];
|
|
31
|
+
const result = Joi.validate(item[0], compiled, item[2] || options);
|
|
32
|
+
|
|
33
|
+
const err = result.error;
|
|
34
|
+
const value = result.value;
|
|
35
|
+
|
|
36
|
+
if (err !== null && item[1]) {
|
|
37
|
+
console.log(err);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (err === null && !item[1]) {
|
|
41
|
+
console.log(item[0]);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
expect(err === null).to.equal(item[1]);
|
|
45
|
+
|
|
46
|
+
if (item.length >= 4) {
|
|
47
|
+
const comparator = item[3];
|
|
48
|
+
if (item[1]) {
|
|
49
|
+
expect(value).to.deep.equal(comparator);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
if (comparator instanceof RegExp) {
|
|
53
|
+
expect(err.message).to.match(comparator);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
expect(err.message).to.deep.equal(comparator);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (callback) {
|
|
63
|
+
callback();
|
|
64
|
+
}
|
|
65
|
+
};
|