mirror of https://gitee.com/bigwinds/arangodb
910 lines
26 KiB
JavaScript
Executable File
910 lines
26 KiB
JavaScript
Executable File
// Load modules
|
|
|
|
var Lab = require('lab');
|
|
var Joi = require('../lib');
|
|
var Helper = require('./helper');
|
|
|
|
|
|
// Declare internals
|
|
|
|
var internals = {};
|
|
|
|
|
|
// Test shortcuts
|
|
|
|
var expect = Lab.expect;
|
|
var before = Lab.before;
|
|
var after = Lab.after;
|
|
var describe = Lab.experiment;
|
|
var it = Lab.test;
|
|
|
|
|
|
describe('object', function () {
|
|
|
|
it('converts a json string to an object', function (done) {
|
|
|
|
Joi.object().validate('{"hi":true}', function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
expect(value.hi).to.equal(true);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('errors on non-object string', function (done) {
|
|
|
|
Joi.object().validate('a string', function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(value).to.equal('a string');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should validate an object', function (done) {
|
|
|
|
var schema = Joi.object().required();
|
|
Helper.validate(schema, [
|
|
[{}, true],
|
|
[{ hi: true }, true],
|
|
['', false]
|
|
], done);
|
|
});
|
|
|
|
it('retains ignored values', function (done) {
|
|
|
|
var schema = Joi.object();
|
|
schema.validate({ a: 5 }, function (err, value) {
|
|
|
|
expect(value.a).to.equal(5);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('retains skipped values', function (done) {
|
|
|
|
var schema = Joi.object({ b: 5 }).unknown(true);
|
|
schema.validate({ b: '5', a: 5 }, function (err, value) {
|
|
|
|
expect(value.a).to.equal(5);
|
|
expect(value.b).to.equal(5);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('allows any key when schema is undefined', function (done) {
|
|
|
|
Joi.object().validate({ a: 4 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
|
|
Joi.object(undefined).validate({ a: 4 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('allows any key when schema is null', function (done) {
|
|
|
|
Joi.object(null).validate({ a: 4 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('throws on invalid object schema', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
Joi.object(4);
|
|
}).to.throw('Object schema must be a valid object');
|
|
done();
|
|
});
|
|
|
|
it('throws on joi object schema', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
Joi.object(Joi.object());
|
|
}).to.throw('Object schema cannot be a joi schema');
|
|
done();
|
|
});
|
|
|
|
it('skips conversion when value is undefined', function (done) {
|
|
|
|
Joi.object({ a: Joi.object() }).validate(undefined, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
expect(value).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('errors on array', function (done) {
|
|
|
|
Joi.object().validate([1, 2, 3], function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should prevent extra keys from existing by default', function (done) {
|
|
|
|
var schema = Joi.object({ item: Joi.string().required() }).required();
|
|
Helper.validate(schema, [
|
|
[{ item: 'something' }, true],
|
|
[{ item: 'something', item2: 'something else' }, false],
|
|
['', false]
|
|
], done);
|
|
});
|
|
|
|
it('should validate count when min is set', function (done) {
|
|
|
|
var schema = Joi.object().min(3);
|
|
Helper.validate(schema, [
|
|
[{ item: 'something' }, false],
|
|
[{ item: 'something', item2: 'something else' }, false],
|
|
[{ item: 'something', item2: 'something else', item3: 'something something else' }, true],
|
|
['', false]
|
|
], done);
|
|
});
|
|
|
|
it('should validate count when max is set', function (done) {
|
|
|
|
var schema = Joi.object().max(2);
|
|
Helper.validate(schema, [
|
|
[{ item: 'something' }, true],
|
|
[{ item: 'something', item2: 'something else' }, true],
|
|
[{ item: 'something', item2: 'something else', item3: 'something something else' }, false],
|
|
['', false]
|
|
], done);
|
|
});
|
|
|
|
it('should validate count when min and max is set', function (done) {
|
|
|
|
var schema = Joi.object().max(3).min(2);
|
|
Helper.validate(schema, [
|
|
[{ item: 'something' }, false],
|
|
[{ item: 'something', item2: 'something else' }, true],
|
|
[{ item: 'something', item2: 'something else', item3: 'something something else' }, true],
|
|
[{ item: 'something', item2: 'something else', item3: 'something something else', item4: 'item4' }, false],
|
|
['', false]
|
|
], done);
|
|
});
|
|
|
|
it('should validate count when length is set', function (done) {
|
|
|
|
var schema = Joi.object().length(2);
|
|
Helper.validate(schema, [
|
|
[{ item: 'something' }, false],
|
|
[{ item: 'something', item2: 'something else' }, true],
|
|
[{ item: 'something', item2: 'something else', item3: 'something something else' }, false],
|
|
['', false]
|
|
], done);
|
|
});
|
|
|
|
it('should traverse an object and validate all properties in the top level', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
num: Joi.number()
|
|
});
|
|
|
|
Helper.validate(schema, [
|
|
[{ num: 1 }, true],
|
|
[{ num: [1, 2, 3] }, false]
|
|
], done);
|
|
});
|
|
|
|
it('should traverse an object and child objects and validate all properties', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
num: Joi.number(),
|
|
obj: Joi.object({
|
|
item: Joi.string()
|
|
})
|
|
});
|
|
|
|
Helper.validate(schema, [
|
|
[{ num: 1 }, true],
|
|
[{ num: [1, 2, 3] }, false],
|
|
[{ num: 1, obj: { item: 'something' } }, true],
|
|
[{ num: 1, obj: { item: 123 } }, false]
|
|
], done);
|
|
});
|
|
|
|
it('should traverse an object several levels', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
obj: Joi.object({
|
|
obj: Joi.object({
|
|
obj: Joi.object({
|
|
item: Joi.boolean()
|
|
})
|
|
})
|
|
})
|
|
});
|
|
|
|
Helper.validate(schema, [
|
|
[{ num: 1 }, false],
|
|
[{ obj: {} }, true],
|
|
[{ obj: { obj: {} } }, true],
|
|
[{ obj: { obj: { obj: {} } } }, true],
|
|
[{ obj: { obj: { obj: { item: true } } } }, true],
|
|
[{ obj: { obj: { obj: { item: 10 } } } }, false]
|
|
], done);
|
|
});
|
|
|
|
it('should traverse an object several levels with required levels', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
obj: Joi.object({
|
|
obj: Joi.object({
|
|
obj: Joi.object({
|
|
item: Joi.boolean()
|
|
})
|
|
}).required()
|
|
})
|
|
});
|
|
|
|
Helper.validate(schema, [
|
|
[null, false],
|
|
[undefined, true],
|
|
[{}, true],
|
|
[{ obj: {} }, false],
|
|
[{ obj: { obj: {} } }, true],
|
|
[{ obj: { obj: { obj: {} } } }, true],
|
|
[{ obj: { obj: { obj: { item: true } } } }, true],
|
|
[{ obj: { obj: { obj: { item: 10 } } } }, false]
|
|
], done);
|
|
});
|
|
|
|
it('should traverse an object several levels with required levels (without Joi.obj())', function (done) {
|
|
|
|
var schema = {
|
|
obj: {
|
|
obj: {
|
|
obj: {
|
|
item: Joi.boolean().required()
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Helper.validate(schema, [
|
|
[null, false],
|
|
[undefined, true],
|
|
[{}, true],
|
|
[{ obj: {} }, true],
|
|
[{ obj: { obj: {} } }, true],
|
|
[{ obj: { obj: { obj: {} } } }, false],
|
|
[{ obj: { obj: { obj: { item: true } } } }, true],
|
|
[{ obj: { obj: { obj: { item: 10 } } } }, false]
|
|
], done);
|
|
});
|
|
|
|
it('errors on unknown keys when functions allows', function (done) {
|
|
|
|
var schema = Joi.object({ a: Joi.number() }).options({ skipFunctions: true });
|
|
var obj = { a: 5, b: 'value' };
|
|
schema.validate(obj, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('validates both valid() and with()', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
first: Joi.valid('value'),
|
|
second: Joi.any()
|
|
}).with('first', 'second');
|
|
|
|
Helper.validate(schema, [
|
|
[{ first: 'value' }, false]
|
|
], done);
|
|
});
|
|
|
|
describe('#keys', function () {
|
|
|
|
it('allows any key', function (done) {
|
|
|
|
var a = Joi.object({ a: 4 });
|
|
var b = a.keys();
|
|
a.validate({ b: 3 }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
b.validate({ b: 3 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('forbids all keys', function (done) {
|
|
|
|
var a = Joi.object();
|
|
var b = a.keys({});
|
|
a.validate({ b: 3 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
b.validate({ b: 3 }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('adds to existing keys', function (done) {
|
|
|
|
var a = Joi.object({ a: 1 });
|
|
var b = a.keys({ b: 2 });
|
|
a.validate({ a: 1, b: 2 }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
b.validate({ a: 1, b: 2 }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#unknown', function () {
|
|
|
|
it('allows local unknown without applying to children', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: {
|
|
b: Joi.number()
|
|
}
|
|
}).unknown();
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: { b: 5 } }, true],
|
|
[{ a: { b: 'x' } }, false],
|
|
[{ a: { b: 5 }, c: 'ignore' }, true],
|
|
[{ a: { b: 5, c: 'ignore' } }, false]
|
|
], done);
|
|
});
|
|
|
|
it('forbids local unknown without applying to children', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.object({
|
|
b: Joi.number()
|
|
}).unknown()
|
|
}).options({ allowUnknown: false });
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: { b: 5 } }, true],
|
|
[{ a: { b: 'x' } }, false],
|
|
[{ a: { b: 5 }, c: 'ignore' }, false],
|
|
[{ a: { b: 5, c: 'ignore' } }, true]
|
|
], done);
|
|
});
|
|
});
|
|
|
|
describe('#rename', function () {
|
|
|
|
it('allows renaming multiple times with multiple enabled', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
test: Joi.string()
|
|
}).rename('test1', 'test').rename('test2', 'test', { multiple: true });
|
|
|
|
Joi.compile(schema).validate({ test1: 'a', test2: 'b' }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('errors renaming multiple times with multiple disabled', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
test: Joi.string()
|
|
}).rename('test1', 'test').rename('test2', 'test');
|
|
|
|
Joi.compile(schema).validate({ test1: 'a', test2: 'b' }, function (err, value) {
|
|
|
|
expect(err.message).to.equal('value cannot rename child test2 because multiple renames are disabled and another key was already renamed to test');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('errors multiple times when abortEarly is false', function (done) {
|
|
|
|
Joi.object().rename('a', 'b').rename('c', 'b').rename('d', 'b').options({ abortEarly: false }).validate({ a: 1, c: 1, d: 1 }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(err.message).to.equal('value cannot rename child c because multiple renames are disabled and another key was already renamed to b. value cannot rename child d because multiple renames are disabled and another key was already renamed to b');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('aliases a key', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.number(),
|
|
b: Joi.number()
|
|
}).rename('a', 'b', { alias: true });
|
|
|
|
var obj = { a: 10 };
|
|
|
|
Joi.compile(schema).validate(obj, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
expect(value.a).to.equal(10);
|
|
expect(value.b).to.equal(10);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('with override disabled should not allow overwriting existing value', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
test1: Joi.string()
|
|
}).rename('test', 'test1');
|
|
|
|
schema.validate({ test: 'b', test1: 'a' }, function (err, value) {
|
|
|
|
expect(err.message).to.equal('value cannot rename child test because override is disabled and target test1 exists');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('with override enabled should allow overwriting existing value', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
test1: Joi.string()
|
|
}).rename('test', 'test1', { override: true });
|
|
|
|
schema.validate({ test: 'b', test1: 'a' }, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('renames when data is nested in an array via includes', function (done) {
|
|
|
|
var schema = {
|
|
arr: Joi.array().includes(Joi.object({
|
|
one: Joi.string(),
|
|
two: Joi.string()
|
|
}).rename('uno', 'one').rename('dos', 'two'))
|
|
};
|
|
|
|
var data = { arr: [{ uno: '1', dos: '2' }] };
|
|
Joi.object(schema).validate(data, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
expect(value.arr[0].one).to.equal('1');
|
|
expect(value.arr[0].two).to.equal('2');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('applies rename and validation in the correct order regardless of key order', function (done) {
|
|
|
|
var schema1 = Joi.object({
|
|
a: Joi.number()
|
|
}).rename('b', 'a');
|
|
|
|
var input1 = { b: '5' };
|
|
|
|
schema1.validate(input1, function (err1, value1) {
|
|
|
|
expect(err1).to.not.exist;
|
|
expect(value1.b).to.not.exist;
|
|
expect(value1.a).to.equal(5);
|
|
|
|
var schema2 = Joi.object({ a: Joi.number(), b: Joi.any() }).rename('b', 'a');
|
|
var input2 = { b: '5' };
|
|
|
|
schema2.validate(input2, function (err2, value2) {
|
|
|
|
expect(err2).to.not.exist;
|
|
expect(value2.b).to.not.exist;
|
|
expect(value2.a).to.equal(5);
|
|
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('sets the default value after key is renamed', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
foo2: Joi.string().default('test')
|
|
}).rename('foo', 'foo2');
|
|
|
|
var input = {};
|
|
|
|
Joi.validate(input, schema, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
expect(value.foo2).to.equal('test');
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should be able to rename keys that are empty strings', function (done) {
|
|
|
|
var schema = Joi.object().rename('', 'notEmpty');
|
|
var input = {
|
|
'': 'something'
|
|
};
|
|
|
|
schema.validate(input, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
expect(value['']).to.not.exist;
|
|
expect(value.notEmpty).to.equal('something');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('should not create new keys when they key in question does not exist', function (done) {
|
|
|
|
var schema = Joi.object().rename('b', '_b');
|
|
|
|
var input = {
|
|
a: 'something'
|
|
};
|
|
|
|
schema.validate(input, function (err, value) {
|
|
|
|
expect(err).to.not.exist;
|
|
expect(value).to.have.keys(['a']);
|
|
expect(value.a).to.equal('something');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#describe', function () {
|
|
|
|
it('return empty description when no schema defined', function (done) {
|
|
|
|
var schema = Joi.object();
|
|
var desc = schema.describe();
|
|
expect(desc).to.deep.equal({
|
|
type: 'object'
|
|
});
|
|
done();
|
|
});
|
|
|
|
it('respects the shallow parameter', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
name: Joi.string(),
|
|
child: Joi.object({
|
|
name: Joi.string()
|
|
})
|
|
});
|
|
|
|
expect(schema.describe(true)).to.not.contain.key('children');
|
|
expect(schema.describe()).to.contain.key('children');
|
|
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('#length', function () {
|
|
|
|
it('throws when length is not a number', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
Joi.object().length('a');
|
|
}).to.throw('limit must be a positive integer');
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('#min', function () {
|
|
|
|
it('throws when limit is not a number', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
Joi.object().min('a');
|
|
}).to.throw('limit must be a positive integer');
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('#max', function () {
|
|
|
|
it('throws when limit is not a number', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
Joi.object().max('a');
|
|
}).to.throw('limit must be a positive integer');
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('#pattern', function () {
|
|
|
|
it('validates unknown keys using a pattern', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: Joi.number()
|
|
}).pattern(/\d+/, Joi.boolean()).pattern(/\w\w+/, 'x');
|
|
|
|
Joi.validate({ bb: 'y', 5: 'x' }, schema, { abortEarly: false }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(err.message).to.equal('5 must be a boolean. bb must be one of x');
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: 5 }, true],
|
|
[{ a: 'x' }, false],
|
|
[{ b: 'x' }, false],
|
|
[{ bb: 'x' }, true],
|
|
[{ 5: 'x' }, false],
|
|
[{ 5: false }, true],
|
|
[{ 5: undefined }, true]
|
|
], done)
|
|
});
|
|
});
|
|
|
|
it('validates unknown keys using a pattern (nested)', function (done) {
|
|
|
|
var schema = {
|
|
x: Joi.object({
|
|
a: Joi.number()
|
|
}).pattern(/\d+/, Joi.boolean()).pattern(/\w\w+/, 'x')
|
|
};
|
|
|
|
Joi.validate({ x: { bb: 'y', 5: 'x' } }, schema, { abortEarly: false }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(err.message).to.equal('5 must be a boolean. bb must be one of x');
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('errors when using a pattern on empty schema with unknown(false) and pattern mismatch', function (done) {
|
|
|
|
var schema = Joi.object().pattern(/\d/, Joi.number()).unknown(false);
|
|
|
|
Joi.validate({ a: 5 }, schema, { abortEarly: false }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(err.message).to.equal('a is not allowed');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#with', function () {
|
|
|
|
it('should throw an error when a parameter is not a string', function (done) {
|
|
|
|
try {
|
|
Joi.object().with({});
|
|
var error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
|
|
try {
|
|
Joi.object().with(123);
|
|
error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
done();
|
|
});
|
|
|
|
it('should validate correctly when key is an empty string', function (done) {
|
|
|
|
var schema = Joi.object().with('', 'b');
|
|
Helper.validate(schema, [
|
|
[{ c: 'hi', d: 'there' }, true],
|
|
]);
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('#without', function () {
|
|
|
|
it('should throw an error when a parameter is not a string', function (done) {
|
|
|
|
try {
|
|
Joi.object().without({});
|
|
var error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
|
|
try {
|
|
Joi.object().without(123);
|
|
error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
|
|
|
|
done();
|
|
});
|
|
|
|
it('should validate correctly when key is an empty string', function (done) {
|
|
|
|
var schema = Joi.object().without('', 'b');
|
|
Helper.validate(schema, [
|
|
[{ a: 'hi', b: 'there' }, true]
|
|
]);
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('#xor', function () {
|
|
|
|
it('should throw an error when a parameter is not a string', function (done) {
|
|
|
|
try {
|
|
Joi.object().xor({});
|
|
var error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
|
|
try {
|
|
Joi.object().xor(123);
|
|
error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
done();
|
|
});
|
|
});
|
|
|
|
describe('#or', function () {
|
|
|
|
it('should throw an error when a parameter is not a string', function (done) {
|
|
|
|
try {
|
|
Joi.object().or({});
|
|
var error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
|
|
try {
|
|
Joi.object().or(123);
|
|
error = false;
|
|
}
|
|
catch (e) {
|
|
error = true;
|
|
}
|
|
expect(error).to.equal(true);
|
|
done();
|
|
});
|
|
|
|
it('errors multiple levels deep', function (done) {
|
|
|
|
Joi.object({
|
|
a: {
|
|
b: Joi.object().or('x', 'y')
|
|
}
|
|
}).validate({ a: { b: { c: 1 } } }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(err.message).to.equal('value must contain at least one of x, y');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('#assert', function () {
|
|
|
|
it('validates upwards reference', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: {
|
|
b: Joi.string(),
|
|
c: Joi.number()
|
|
},
|
|
d: {
|
|
e: Joi.any()
|
|
}
|
|
}).assert(Joi.ref('d/e', { separator: '/' }), Joi.ref('a.c'), 'equal to a.c');
|
|
|
|
schema.validate({ a: { b: 'x', c: 5 }, d: { e: 6 } }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(err.message).to.equal('value validation failed because d.e failed to equal to a.c');
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: { b: 'x', c: 5 }, d: { e: 5 } }, true]
|
|
], done);
|
|
});
|
|
});
|
|
|
|
it('validates upwards reference with implicit context', function (done) {
|
|
|
|
var schema = Joi.object({
|
|
a: {
|
|
b: Joi.string(),
|
|
c: Joi.number()
|
|
},
|
|
d: {
|
|
e: Joi.any()
|
|
}
|
|
}).assert('d.e', Joi.ref('a.c'), 'equal to a.c');
|
|
|
|
schema.validate({ a: { b: 'x', c: 5 }, d: { e: 6 } }, function (err, value) {
|
|
|
|
expect(err).to.exist;
|
|
expect(err.message).to.equal('value validation failed because d.e failed to equal to a.c');
|
|
|
|
Helper.validate(schema, [
|
|
[{ a: { b: 'x', c: 5 }, d: { e: 5 } }, true]
|
|
], done);
|
|
});
|
|
});
|
|
|
|
it('throws when context is at root level', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
var schema = Joi.object({
|
|
a: {
|
|
b: Joi.string(),
|
|
c: Joi.number()
|
|
},
|
|
d: {
|
|
e: Joi.any()
|
|
}
|
|
}).assert('a', Joi.ref('d.e'), 'equal to d.e');
|
|
}).to.throw('Cannot use assertions for root level references - use direct key rules instead');
|
|
done();
|
|
});
|
|
|
|
it('allows root level context ref', function (done) {
|
|
|
|
expect(function () {
|
|
|
|
var schema = Joi.object({
|
|
a: {
|
|
b: Joi.string(),
|
|
c: Joi.number()
|
|
},
|
|
d: {
|
|
e: Joi.any()
|
|
}
|
|
}).assert('$a', Joi.ref('d.e'), 'equal to d.e');
|
|
}).to.not.throw();
|
|
done();
|
|
});
|
|
});
|
|
});
|