mirror of https://gitee.com/bigwinds/arangodb
390 lines
11 KiB
JavaScript
Executable File
390 lines
11 KiB
JavaScript
Executable File
// Load modules
|
|
|
|
var Lab = require('lab');
|
|
var Code = require('code');
|
|
var Joi = require('../lib');
|
|
var Helper = require('./helper');
|
|
|
|
|
|
// Declare internals
|
|
|
|
var internals = {};
|
|
|
|
|
|
// Test shortcuts
|
|
|
|
var lab = exports.lab = Lab.script();
|
|
var before = lab.before;
|
|
var after = lab.after;
|
|
var describe = lab.describe;
|
|
var it = lab.it;
|
|
var expect = Code.expect;
|
|
|
|
|
|
describe('ref', function () {
|
|
|
|
it('uses ref as a valid value', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.ref('b'),
|
|
b: Joi.any()
|
|
});
|
|
|
|
schema.validate({ a: 5, b: 6 }, function (err, value) {
|
|
|
|
expect(err).to.exist();
|
|
expect(err.message).to.equal('child "a" fails because ["a" must be one of [ref:b]]');
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: 5 }, false],
|
|
[{ b: 5 }, true],
|
|
[{ a: 5, b: 5 }, true],
|
|
[{ a: '5', b: '5' }, true]
|
|
], done);
|
|
});
|
|
});
|
|
|
|
it('uses ref as a valid value (empty key)', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.ref(''),
|
|
'': Joi.any()
|
|
});
|
|
|
|
schema.validate({ a: 5, '': 6 }, function (err, value) {
|
|
|
|
expect(err).to.exist();
|
|
expect(err.message).to.equal('child "a" fails because ["a" must be one of [ref:]]');
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: 5 }, false],
|
|
[{ '': 5 }, true],
|
|
[{ a: 5, '': 5 }, true],
|
|
[{ a: '5', '': '5' }, true]
|
|
], done);
|
|
});
|
|
});
|
|
|
|
it('uses ref with nested keys as a valid value', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.ref('b.c'),
|
|
b: {
|
|
c: Joi.any()
|
|
}
|
|
});
|
|
|
|
schema.validate({ a: 5, b: { c: 6 } }, function (err, value) {
|
|
|
|
expect(err).to.exist();
|
|
expect(err.message).to.equal('child "a" fails because ["a" must be one of [ref:b.c]]');
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: 5 }, false],
|
|
[{ b: { c: 5 } }, true],
|
|
[{ a: 5, b: 5 }, false],
|
|
[{ a: '5', b: { c: '5' } }, true]
|
|
], done);
|
|
});
|
|
});
|
|
|
|
it('uses ref with combined nested keys in sub child', function (done) {
|
|
|
|
var ref = Joi.ref('b.c');
|
|
expect(ref.root).to.equal('b');
|
|
|
|
var schema = Joi.object({
|
|
a: ref,
|
|
b: {
|
|
c: Joi.any()
|
|
}
|
|
});
|
|
|
|
var input = { a: 5, b: { c: 5 } };
|
|
schema.validate(input, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
|
|
var parent = Joi.object({
|
|
e: schema
|
|
});
|
|
|
|
parent.validate({ e: input }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('uses ref reach options', function (done) {
|
|
|
|
var ref = Joi.ref('b/c', { separator: '/' });
|
|
expect(ref.root).to.equal('b');
|
|
|
|
var schema = Joi.object({
|
|
a: ref,
|
|
b: {
|
|
c: Joi.any()
|
|
}
|
|
});
|
|
|
|
schema.validate({ a: 5, b: { c: 5 } }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('ignores the order in which keys are defined', function (done) {
|
|
|
|
var ab = Joi.object({
|
|
a: {
|
|
c: Joi.number()
|
|
},
|
|
b: Joi.ref('a.c')
|
|
});
|
|
|
|
ab.validate({ a: { c: '5' }, b: 5 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
|
|
var ba = Joi.object({
|
|
b: Joi.ref('a.c'),
|
|
a: {
|
|
c: Joi.number()
|
|
}
|
|
});
|
|
|
|
ba.validate({ a: { c: '5' }, b: 5 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('uses ref as default value', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.default(Joi.ref('b')),
|
|
b: Joi.any()
|
|
});
|
|
|
|
schema.validate({ b: 6 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
expect(value).to.deep.equal({ a: 6, b: 6 });
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('uses ref as default value regardless of order', function (done) {
|
|
|
|
var ab = Joi.object({
|
|
a: Joi.default(Joi.ref('b')),
|
|
b: Joi.number()
|
|
});
|
|
|
|
ab.validate({ b: '6' }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
expect(value).to.deep.equal({ a: 6, b: 6 });
|
|
|
|
var ba = Joi.object({
|
|
b: Joi.number(),
|
|
a: Joi.default(Joi.ref('b'))
|
|
});
|
|
|
|
ba.validate({ b: '6' }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
expect(value).to.deep.equal({ a: 6, b: 6 });
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('ignores the order in which keys are defined with alternatives', function (done) {
|
|
|
|
var a = { c: Joi.number() };
|
|
var b = [Joi.ref('a.c'), Joi.ref('c')];
|
|
var c = Joi.number();
|
|
|
|
Helper.validate({ a: a, b: b, c: c }, [
|
|
[{ a: {} }, true],
|
|
[{ a: { c: '5' }, b: 5 }, true],
|
|
[{ a: { c: '5' }, b: 6, c: '6' }, true],
|
|
[{ a: { c: '5' }, b: 7, c: '6' }, false]
|
|
]);
|
|
|
|
Helper.validate({ b: b, a: a, c: c }, [
|
|
[{ a: {} }, true],
|
|
[{ a: { c: '5' }, b: 5 }, true],
|
|
[{ a: { c: '5' }, b: 6, c: '6' }, true],
|
|
[{ a: { c: '5' }, b: 7, c: '6' }, false]
|
|
]);
|
|
|
|
Helper.validate({ b: b, c: c, a: a }, [
|
|
[{ a: {} }, true],
|
|
[{ a: { c: '5' }, b: 5 }, true],
|
|
[{ a: { c: '5' }, b: 6, c: '6' }, true],
|
|
[{ a: { c: '5' }, b: 7, c: '6' }, false]
|
|
]);
|
|
|
|
Helper.validate({ a: a, c: c, b: b }, [
|
|
[{ a: {} }, true],
|
|
[{ a: { c: '5' }, b: 5 }, true],
|
|
[{ a: { c: '5' }, b: 6, c: '6' }, true],
|
|
[{ a: { c: '5' }, b: 7, c: '6' }, false]
|
|
]);
|
|
|
|
Helper.validate({ c: c, a: a, b: b }, [
|
|
[{ a: {} }, true],
|
|
[{ a: { c: '5' }, b: 5 }, true],
|
|
[{ a: { c: '5' }, b: 6, c: '6' }, true],
|
|
[{ a: { c: '5' }, b: 7, c: '6' }, false]
|
|
]);
|
|
|
|
Helper.validate({ c: c, b: b, a: a }, [
|
|
[{ a: {} }, true],
|
|
[{ a: { c: '5' }, b: 5 }, true],
|
|
[{ a: { c: '5' }, b: 6, c: '6' }, true],
|
|
[{ a: { c: '5' }, b: 7, c: '6' }, false]
|
|
], done);
|
|
});
|
|
|
|
it('uses context as default value', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.default(Joi.ref('$x')),
|
|
b: Joi.any()
|
|
});
|
|
|
|
Joi.validate({ b: 6 }, schema, { context: { x: 22 } }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
expect(value).to.deep.equal({ a: 22, b: 6 });
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('uses context as default value with custom prefix', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.default(Joi.ref('%x', { contextPrefix: '%' })),
|
|
b: Joi.any()
|
|
});
|
|
|
|
Joi.validate({ b: 6 }, schema, { context: { x: 22 } }, function (err, value) {
|
|
|
|
expect(err).to.not.exist();
|
|
expect(value).to.deep.equal({ a: 22, b: 6 });
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('uses context as a valid value', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.ref('$x'),
|
|
b: Joi.any()
|
|
});
|
|
|
|
Joi.validate({ a: 5, b: 6 }, schema, { context: { x: 22 } }, function (err, value) {
|
|
|
|
expect(err).to.exist();
|
|
expect(err.message).to.equal('child "a" fails because ["a" must be one of [context:x]]');
|
|
|
|
Helper.validateOptions(schema, [
|
|
[{ a: 5 }, false],
|
|
[{ a: 22 }, true],
|
|
[{ b: 5 }, true],
|
|
[{ a: 22, b: 5 }, true],
|
|
[{ a: '22', b: '5' }, false]
|
|
], { context: { x: 22 } }, done);
|
|
});
|
|
});
|
|
|
|
it('uses context in when condition', function (done) {
|
|
|
|
var schema = {
|
|
a: Joi.boolean().when('$x', { is: Joi.exist(), otherwise: Joi.forbidden() })
|
|
};
|
|
|
|
Helper.validate(schema, [
|
|
[{}, true],
|
|
[{ a: 'x' }, false],
|
|
[{ a: true }, false],
|
|
[{}, true, { context: {} }],
|
|
[{ a: 'x' }, false, { context: {} }],
|
|
[{ a: true }, false, { context: {} }],
|
|
[{}, true, { context: { x: 1 } }],
|
|
[{ a: 'x' }, false, { context: { x: 1 } }],
|
|
[{ a: true }, true, { context: { x: 1 } }]
|
|
], done);
|
|
});
|
|
|
|
it('uses nested context in when condition', function (done) {
|
|
|
|
var schema = {
|
|
a: Joi.boolean().when('$x.y', { is: Joi.exist(), otherwise: Joi.forbidden() })
|
|
};
|
|
|
|
Helper.validate(schema, [
|
|
[{}, true],
|
|
[{ a: 'x' }, false],
|
|
[{ a: true }, false],
|
|
[{}, true, { context: {} }],
|
|
[{ a: 'x' }, false, { context: {} }],
|
|
[{ a: true }, false, { context: {} }],
|
|
[{}, true, { context: { x: 1 } }],
|
|
[{ a: 'x' }, false, { context: { x: 1 } }],
|
|
[{ a: true }, false, { context: { x: 1 } }],
|
|
[{}, true, { context: { x: {} } }],
|
|
[{ a: 'x' }, false, { context: { x: {} } }],
|
|
[{ a: true }, false, { context: { x: {} } }],
|
|
[{}, true, { context: { x: { y: 1 } } }],
|
|
[{ a: 'x' }, false, { context: { x: { y: 1 } } }],
|
|
[{ a: true }, true, { context: { x: { y: 1 } } }]
|
|
], done);
|
|
});
|
|
|
|
it('describes schema with ref', function (done) {
|
|
|
|
var desc = Joi.compile(Joi.ref('a.b')).describe();
|
|
expect(Joi.isRef(desc.valids[0])).to.be.true();
|
|
done();
|
|
});
|
|
|
|
describe('#create', function () {
|
|
|
|
it('throws when key is missing', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
Joi.ref(5);
|
|
}).to.throw('Invalid reference key: 5');
|
|
done();
|
|
});
|
|
|
|
it('finds root with default separator', function (done) {
|
|
|
|
expect(Joi.ref('a.b.c').root).to.equal('a');
|
|
done();
|
|
});
|
|
|
|
it('finds root with default separator and options', function (done) {
|
|
|
|
expect(Joi.ref('a.b.c', {}).root).to.equal('a');
|
|
done();
|
|
});
|
|
|
|
it('finds root with custom separator', function (done) {
|
|
|
|
expect(Joi.ref('a+b+c', { separator: '+' }).root).to.equal('a');
|
|
done();
|
|
});
|
|
});
|
|
});
|