Skip to content

Commit

Permalink
Correctly merge language options. Fixes #1658.
Browse files Browse the repository at this point in the history
  • Loading branch information
Marsup committed Nov 24, 2018
1 parent 73cbaeb commit e63e3fb
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/types/any/settings.js
Expand Up @@ -24,8 +24,8 @@ exports.concat = function (target, source) {

Object.assign(obj, source);

if (language) {
obj.language = Hoek.applyToDefaults(obj.language, language);
if (language && target && target.language) {
obj.language = Hoek.applyToDefaults(target.language, language);
}

if (obj[Symbols.settingsCache]) {
Expand Down
90 changes: 90 additions & 0 deletions test/index.js
Expand Up @@ -3920,6 +3920,96 @@ describe('Joi', () => {
}]);
});

it('merges languages when multiple extensions extend the same type', () => {

const customJoiWithBoth = Joi.extend([
(joi) => ({
base: joi.number(),
name: 'number',
language: { foo: 'foo' },
rules: [{
name: 'foo',
validate(params, value, state, options) {

return this.createError('number.foo', null, state, options);
}
}]
}),
(joi) => ({
base: joi.number(),
name: 'number',
language: { bar: 'bar' },
rules: [{
name: 'bar',
validate(params, value, state, options) {

return this.createError('number.bar', null, state, options);
}
}]
})
]);

expect(customJoiWithBoth.number().foo().validate(0).error).to.be.an.error('"value" foo');
expect(customJoiWithBoth.number().bar().validate(0).error).to.be.an.error('"value" bar');

const customJoiWithFirst = Joi.extend([
(joi) => ({
base: joi.number(),
name: 'number',
language: { foo: 'foo' },
rules: [{
name: 'foo',
validate(params, value, state, options) {

return this.createError('number.foo', null, state, options);
}
}]
}),
(joi) => ({
base: joi.number(),
name: 'number',
rules: [{
name: 'bar',
validate(params, value, state, options) {

return this.createError('number.base', null, state, options);
}
}]
})
]);

expect(customJoiWithFirst.number().foo().validate(0).error).to.be.an.error('"value" foo');
expect(customJoiWithFirst.number().bar().validate(0).error).to.be.an.error('"value" must be a number');

const customJoiWithSecond = Joi.extend([
(joi) => ({
base: joi.number(),
name: 'number',
rules: [{
name: 'foo',
validate(params, value, state, options) {

return this.createError('number.base', null, state, options);
}
}]
}),
(joi) => ({
base: joi.number(),
name: 'number',
language: { bar: 'bar' },
rules: [{
name: 'bar',
validate(params, value, state, options) {

return this.createError('number.bar', null, state, options);
}
}]
})
]);

expect(customJoiWithSecond.number().foo().validate(0).error).to.be.an.error('"value" must be a number');
expect(customJoiWithSecond.number().bar().validate(0).error).to.be.an.error('"value" bar');
});
});

describe('defaults()', () => {
Expand Down
45 changes: 45 additions & 0 deletions test/types/any.js
Expand Up @@ -292,6 +292,51 @@ describe('any', () => {
}]
});
});

it('merges options properly', () => {

const baseSchema = Joi.any();
expect(baseSchema.describe().options).to.undefined();

const languageSchema = baseSchema.options({ language: { type: { foo: 'foo' } } });
expect(languageSchema.describe().options).to.equal({ language: { type: { foo: 'foo' } } });

const normalOptionSchema = baseSchema.options({ abortEarly: true });
expect(normalOptionSchema.describe().options).to.equal({ abortEarly: true });

const normalOptionsOverLanguageSchema = languageSchema.options({ abortEarly: true });
expect(normalOptionsOverLanguageSchema.describe().options).to.equal({
abortEarly: true,
language: {
type: {
foo: 'foo'
}
}
});

const languageOptionsOverNormalOptionsSchema = normalOptionSchema.options({ language: { type: { foo: 'foo' } } });
expect(languageOptionsOverNormalOptionsSchema.describe().options).to.equal({
abortEarly: true,
language: {
type: {
foo: 'foo'
}
}
});

const languageOptionsOverLanguageOptionsSchema = languageSchema.options({
language: {
type: { bar: 'bar' },
type2: { foo: 'foo' }
}
});
expect(languageOptionsOverLanguageOptionsSchema.describe().options).to.equal({
language: {
type: { foo: 'foo', bar: 'bar' },
type2: { foo: 'foo' }
}
});
});
});

describe('label()', () => {
Expand Down

0 comments on commit e63e3fb

Please sign in to comment.