Skip to content

Commit

Permalink
Support flag describe setter override. Closes #2039
Browse files Browse the repository at this point in the history
  • Loading branch information
hueniverse committed Aug 10, 2019
1 parent ce4f2d4 commit 9d52dc2
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 6 deletions.
4 changes: 4 additions & 0 deletions lib/extend.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ exports.type = function (from, options) {
def.args = parent.args;
}

// Flags

def.flags = Object.assign({}, parent.flags, def.flags);

// Prepare

def.prepare = internals.prepare(def.prepare, parent.prepare);
Expand Down
5 changes: 3 additions & 2 deletions lib/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ exports.describe = function (schema) {

const item = { name: rule.name };

for (const custom of ['keep', 'message', 'warn']) {
for (const custom in schema._definition.modifiers) {
if (rule[custom] !== undefined) {
item[custom] = internals.describe(rule[custom]);
}
Expand Down Expand Up @@ -243,7 +243,8 @@ internals.Builder = class {

if (desc.flags) {
for (const flag in desc.flags) {
schema = schema[flag](this.build(desc.flags[flag]));
const setter = def.flags[flag] && def.flags[flag].setter || flag;
schema = schema[setter](this.build(desc.flags[flag]));
}
}

Expand Down
1 change: 1 addition & 0 deletions lib/schemas.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ exports.extension = Joi.object({
Joi.func().maxArity(3),
Joi.object({ method: Joi.func().maxArity(3).required(), from: Joi.array().items(Joi.string()).single() })
],
flags: Joi.object().pattern(internals.nameRx, Joi.object({ setter: Joi.string() })),
initialize: Joi.func().arity(1),
messages: [Joi.object(), Joi.string()],
fork: Joi.func().arity(3),
Expand Down
32 changes: 32 additions & 0 deletions test/extend.js
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,38 @@ describe('extension', () => {
expect(Joi.isRef(schema.foo('bar', Joi.ref('a.b')).validate(null).value.second)).to.be.true();
});

it('extends with flag rule (customer setter)', () => {

const custom = Joi.extend({
type: 'special',
flags: {
xfoo: {
setter: 'foo'
}
},
validate(schema, value, helpers) {

return { value: schema.$_getFlag('xfoo') };
},
rules: {
foo: {
method(first, second) {

Joi.assert(first, Joi.string());
Joi.assert(second, Joi.object().ref());

return this.$_setFlag('xfoo', { first, second });
}
}
}
});

const schema = custom.special();
expect(schema.foo('bar').validate(null)).to.equal({ value: { first: 'bar', second: undefined } });
expect(schema.foo('bar', Joi.ref('a.b')).validate(null).value.first).to.equal('bar');
expect(Joi.isRef(schema.foo('bar', Joi.ref('a.b')).validate(null).value.second)).to.be.true();
});

it('defines a rule that can change the value', () => {

const custom = Joi.extend({
Expand Down
17 changes: 13 additions & 4 deletions test/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ describe('Manifest', () => {
const custom = Joi.extend({
type: 'fancy',
base: Joi.object({ a: Joi.number() }),
flags: {
presence: {} // For coverage
},
initialize(schema) {

schema.$_terms.fancy = [];
Expand All @@ -473,11 +476,14 @@ describe('Manifest', () => {
}
});

const schema = custom.fancy().pants('green');
const schema = custom.fancy().pants('green').required();
const desc = schema.describe();

expect(desc).to.equal({
type: 'fancy',
flags: {
presence: 'required'
},
keys: {
a: { type: 'number' }
},
Expand All @@ -493,6 +499,9 @@ describe('Manifest', () => {
const custom = Joi.extend({
type: 'million',
base: Joi.number(),
flags: {
sizable: { setter: 'big' }
},
messages: {
'million.base': '"{{#label}}" must be at least a million',
'million.big': '"{{#label}}" must be at least five millions',
Expand All @@ -517,7 +526,7 @@ describe('Manifest', () => {

// Check flags for global state

if (schema.$_getFlag('big') &&
if (schema.$_getFlag('sizable') &&
value < 5000000) {

return { value, errors: helpers.error('million.big') };
Expand All @@ -528,7 +537,7 @@ describe('Manifest', () => {
alias: 'large',
method() {

return this.$_setFlag('big', true);
return this.$_setFlag('sizable', true);
}
},
round: {
Expand Down Expand Up @@ -624,7 +633,7 @@ describe('Manifest', () => {
e: {
type: 'million',
flags: {
big: true
sizable: true
}
}
}
Expand Down

0 comments on commit 9d52dc2

Please sign in to comment.