You need to set a selectorSettings default, and conditionally strip it out based on the value of selectorStrategy.
Let's walk through your two use cases.
Removing a key based on sibling value
const thing = {
selectorStrategy: 'roulette',
selectorSettings: { tournamentSize: 3 },
};
joi.validate(thing, schema, { stripUnknown: true} );
selectorSettings won't be removed by the stripUnknown option, because the key is not unknown - it's in your schema.
We need to explicitly strip it out based on the value of selectorStrategy:
.when('selectorStrategy', {
is: 'tournament',
otherwise: joi.strip(),
}),
Adding / validating keys based on sibling value
const thing = {
selectorStrategy: 'tournament'
};
joi.validate(thing, schema);
The code is not setting a default for the selectorSettings key itself, only its properties. Since selectorSettings is not required, the validation passes.
We need to set a default:
selectorSettings: joi
.object()
.default({ tournamentSize: 2, baseWeight: 1 })
Modified code that handles both cases would look like this:
const joi = require('joi');
const schema = {
selectorStrategy: joi
.string()
.valid(['tournament', 'roulette'])
.default('tournament'),
selectorSettings: joi
.object()
.default({ tournamentSize: 2, baseWeight: 1 })
.keys({
tournamentSize: joi
.number()
.integer()
.default(2),
baseWeight: joi
.number()
.integer()
.default(1),
})
.when('selectorStrategy', {
is: 'tournament',
otherwise: joi.strip(),
}),
};
Examples
// should remove settings when not a tournament
var thing = {
selectorStrategy: 'roulette',
selectorSettings: { tournamentSize: 3 },
};
// returns
{
"selectorStrategy": "roulette"
}
.
// should insert default settings
var thing = {
selectorStrategy: 'tournament'
};
// returns
{
"selectorStrategy": "tournament",
"selectorSettings": {
"tournamentSize": 2,
"baseWeight": 1
}
}
.
// should add missing baseWeight default
var thing = {
selectorStrategy: 'tournament',
selectorSettings: { tournamentSize: 5 }
};
// returns
{
"selectorStrategy": "tournament",
"selectorSettings": {
"tournamentSize": 5,
"baseWeight": 1
}
}