Skip to content

Commit

Permalink
Support length(). Closes #2732
Browse files Browse the repository at this point in the history
  • Loading branch information
hueniverse committed Jan 26, 2022
1 parent 7e5aebf commit e250c42
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
1 change: 1 addition & 0 deletions API.md
Expand Up @@ -252,6 +252,7 @@ The reference names can have one of the following prefixes:

The formula syntax also supports built-in functions:
- `if(condition, then, otherwise)` - returns `then` when `condition` is truthy, otherwise `otherwise`.
- `length(item)` - reutrn the length of an array or string, the number of keys of an object, otherwise `null`.
- `msg(code)` - embeds another error code message.
- `number(value)` - cast value to a number.

Expand Down
17 changes: 17 additions & 0 deletions lib/template.js
Expand Up @@ -385,6 +385,23 @@ internals.functions = {
return condition ? then : otherwise;
},

length(item) {

if (typeof item === 'string') {
return item.length;
}

if (!item || typeof item !== 'object') {
return null;
}

if (Array.isArray(item)) {
return item.length;
}

return Object.keys(item).length;
},

msg(code) {

const [value, state, prefs, local, options] = this;
Expand Down
66 changes: 66 additions & 0 deletions test/template.js
Expand Up @@ -201,5 +201,71 @@ describe('Template', () => {
Helper.validate(schema, { context: { x: {} } }, [[4, false, '"value" must be [{number(1) + number(true) + number(false) + number("1") + number($x)}]']]);
});
});

describe('length()', () => {

it('calculates object size', () => {

const schema = Joi.object({
a: Joi.array().length(Joi.x('{length(b)}')),
b: Joi.object()
});

Helper.validate(schema, [
[{ a: [1, 2], b: { a: true, b: true } }, true],
[{ a: [1, 2, 3], b: { a: true, b: true } }, false, '"a" must contain {length(b)} items']
]);
});

it('calcualtes array size', () => {

const schema = Joi.object({
a: Joi.array().length(Joi.x('{length(b)}')),
b: Joi.array()
});

Helper.validate(schema, [
[{ a: [1, 2], b: [2, 3] }, true],
[{ a: [1, 2, 3], b: [1] }, false, '"a" must contain {length(b)} items']
]);
});

it('handles null', () => {

const schema = Joi.object({
a: Joi.array().length(Joi.x('{length(b)}')),
b: Joi.array().allow(null)
});

Helper.validate(schema, [
[{ a: [1], b: null }, false, '"a" limit references "{length(b)}" which must be a positive integer']
]);
});

it('handles strings', () => {

const schema = Joi.object({
a: Joi.array().length(Joi.x('{length(b)}')),
b: Joi.string()
});

Helper.validate(schema, [
[{ a: [1], b: 'x' }, true],
[{ a: [1], b: 'xx' }, false, '"a" must contain {length(b)} items']
]);
});

it('handles items without length', () => {

const schema = Joi.object({
a: Joi.array().length(Joi.x('{length(b)}')),
b: Joi.number()
});

Helper.validate(schema, [
[{ a: [1], b: 1 }, false, '"a" limit references "{length(b)}" which must be a positive integer']
]);
});
});
});
});

0 comments on commit e250c42

Please sign in to comment.