From 5cfde5b84d14a90097c077b35a22eab452b78ed3 Mon Sep 17 00:00:00 2001 From: Eran Hammer Date: Fri, 16 Aug 2019 04:33:49 +0000 Subject: [PATCH] Change compile. Closes #2046. Closes #2049 --- lib/compile.js | 32 ++++++++++++++++++----------- test/base.js | 10 ++++----- test/compile.js | 42 ++++++++++++++++++++++++++++++++++++++ test/index.js | 8 ++++---- test/manifest.js | 2 +- test/types/alternatives.js | 36 ++++++++++++++++---------------- test/types/object.js | 4 ++-- 7 files changed, 92 insertions(+), 42 deletions(-) diff --git a/lib/compile.js b/lib/compile.js index cb8160751..50a84900f 100755 --- a/lib/compile.js +++ b/lib/compile.js @@ -32,20 +32,16 @@ internals.schema = function (Joi, config) { Assert(config !== undefined, 'Invalid undefined schema'); - if (config === null) { - return Joi.valid(null); - } - - if (typeof config === 'string') { - return Joi.string().valid(config); - } + if (Array.isArray(config)) { + Assert(config.length, 'Invalid empty array schema'); - if (typeof config === 'number') { - return Joi.number().valid(config); + if (config.length === 1) { + config = config[0]; + } } - if (typeof config === 'boolean') { - return Joi.boolean().valid(config); + if (internals.simple(config)) { + return Joi.valid(config); } Assert(typeof config === 'object', 'Invalid schema content:', typeof config); @@ -59,7 +55,13 @@ internals.schema = function (Joi, config) { } if (Array.isArray(config)) { - return Joi.alternatives().try(config); + for (const valid of config) { + if (!internals.simple(valid)) { + return Joi.alternatives().try(config); + } + } + + return Joi.valid(...config); } if (config instanceof RegExp) { @@ -146,3 +148,9 @@ internals.walk = function (schema) { return null; }; + + +internals.simple = function (value) { + + return value === null || ['boolean', 'string', 'number'].includes(typeof value); +}; diff --git a/test/base.js b/test/base.js index cf917dd8b..edd9f7d9a 100755 --- a/test/base.js +++ b/test/base.js @@ -414,7 +414,7 @@ describe('any', () => { flags: { only: true, empty: { - type: 'string', + type: 'any', flags: { only: true }, allow: ['', ' '] }, @@ -491,7 +491,7 @@ describe('any', () => { flags: { only: true, empty: { - type: 'string', + type: 'any', flags: { only: true }, allow: [''] }, @@ -530,7 +530,7 @@ describe('any', () => { flags: { only: true, empty: { - type: 'string', + type: 'any', flags: { only: true }, allow: [''] }, @@ -2150,7 +2150,7 @@ describe('any', () => { matches: [{ ref: { path: ['a'] }, is: { - type: 'number', + type: 'any', flags: { only: true, presence: 'required' @@ -3082,7 +3082,7 @@ describe('any', () => { matches: [{ ref: { path: ['a'] }, is: { - type: 'number', + type: 'any', flags: { only: true, presence: 'required' diff --git a/test/compile.js b/test/compile.js index 39e7dcfc8..1c00e6d93 100755 --- a/test/compile.js +++ b/test/compile.js @@ -263,6 +263,48 @@ describe('cast', () => { }] ]); }); + + it('compile [null]', () => { + + const schema = Joi.compile([null]); + expect(schema).to.equal(Joi.valid(null)); + }); + + it('compile [1]', () => { + + const schema = Joi.compile([1]); + expect(schema).to.equal(Joi.valid(1)); + }); + + it('compile ["a"]', () => { + + const schema = Joi.compile(['a']); + expect(schema).to.equal(Joi.valid('a')); + }); + + it('compile [null, null, null]', () => { + + const schema = Joi.compile([null]); + expect(schema).to.equal(Joi.valid(null)); + }); + + it('compile [1, 2, 3]', () => { + + const schema = Joi.compile([1, 2, 3]); + expect(schema).to.equal(Joi.valid(1, 2, 3)); + }); + + it('compile ["a", "b", "c"]', () => { + + const schema = Joi.compile(['a','b','c']); + expect(schema).to.equal(Joi.valid('a', 'b', 'c')); + }); + + it('compile [null, "a", 1, true]', () => { + + const schema = Joi.compile([null, 'a', 1, true]); + expect(schema).to.equal(Joi.valid(null, 'a', 1, true)); + }); }); describe('compile()', () => { diff --git a/test/index.js b/test/index.js index 5b3ed9d14..d2ba31ef4 100755 --- a/test/index.js +++ b/test/index.js @@ -1385,7 +1385,7 @@ describe('Joi', () => { }, keys: { foo: { - type: 'string', + type: 'any', flags: { description: 'defaulted', presence: 'required', @@ -1417,7 +1417,7 @@ describe('Joi', () => { }, keys: { foo: { - type: 'string', + type: 'any', flags: { presence: 'required', description: 'defaulted', @@ -1433,7 +1433,7 @@ describe('Joi', () => { description: 'defaulted2', presence: 'required' }, - type: 'string', + type: 'any', allow: ['zorg'] } }, @@ -1466,7 +1466,7 @@ describe('Joi', () => { }, keys: { foo: { - type: 'string', + type: 'any', flags: { description: 'defaulted', presence: 'required', diff --git a/test/manifest.js b/test/manifest.js index a6ce819e1..0e562022e 100755 --- a/test/manifest.js +++ b/test/manifest.js @@ -140,7 +140,7 @@ describe('Manifest', () => { type: 'string', flags: { empty: { - type: 'string', + type: 'any', flags: { only: true }, diff --git a/test/types/alternatives.js b/test/types/alternatives.js index 9f41c8fdf..fa56bf78c 100755 --- a/test/types/alternatives.js +++ b/test/types/alternatives.js @@ -109,7 +109,7 @@ describe('alternatives', () => { { ref: { path: ['b'] }, is: { - type: 'number', + type: 'any', flags: { only: true, presence: 'required' @@ -117,7 +117,7 @@ describe('alternatives', () => { allow: [5] }, then: { - type: 'string', + type: 'any', flags: { only: true }, @@ -127,7 +127,7 @@ describe('alternatives', () => { { ref: { path: ['b'] }, is: { - type: 'number', + type: 'any', flags: { only: true, presence: 'required' @@ -135,7 +135,7 @@ describe('alternatives', () => { allow: [6] }, otherwise: { - type: 'string', + type: 'any', flags: { only: true }, @@ -144,7 +144,7 @@ describe('alternatives', () => { }, { schema: { - type: 'string', + type: 'any', flags: { only: true }, @@ -178,7 +178,7 @@ describe('alternatives', () => { { ref: { path: ['b'] }, is: { - type: 'number', + type: 'any', flags: { only: true, presence: 'required' @@ -186,7 +186,7 @@ describe('alternatives', () => { allow: [5] }, then: { - type: 'string', + type: 'any', flags: { only: true }, @@ -195,7 +195,7 @@ describe('alternatives', () => { }, { schema: { - type: 'string', + type: 'any', flags: { only: true }, @@ -229,7 +229,7 @@ describe('alternatives', () => { { ref: { path: ['b'] }, is: { - type: 'number', + type: 'any', flags: { only: true, presence: 'required' @@ -237,7 +237,7 @@ describe('alternatives', () => { allow: [5] }, otherwise: { - type: 'string', + type: 'any', flags: { only: true }, @@ -246,7 +246,7 @@ describe('alternatives', () => { }, { schema: { - type: 'string', + type: 'any', flags: { only: true }, @@ -312,7 +312,7 @@ describe('alternatives', () => { }, matches: [{ schema: { - type: 'string', + type: 'any', flags: { only: true }, @@ -440,7 +440,7 @@ describe('alternatives', () => { type: 'alternatives', matches: [{ is: { - type: 'boolean', + type: 'any', flags: { only: true, presence: 'required' }, allow: [true] }, @@ -450,7 +450,7 @@ describe('alternatives', () => { flags: { empty: { flags: { only: true }, - type: 'string', + type: 'any', allow: [''] } }, @@ -467,7 +467,7 @@ describe('alternatives', () => { type: 'alternatives', matches: [{ is: { - type: 'boolean', + type: 'any', flags: { only: true, presence: 'required' }, allow: [true] }, @@ -478,7 +478,7 @@ describe('alternatives', () => { label: 'Label b', empty: { flags: { only: true }, - type: 'string', + type: 'any', allow: [''] } }, @@ -515,7 +515,7 @@ describe('alternatives', () => { matches: [ { is: { - type: 'boolean', + type: 'any', allow: [true], flags: { only: true, @@ -561,7 +561,7 @@ describe('alternatives', () => { matches: [ { is: { - type: 'boolean', + type: 'any', allow: [true], flags: { only: true, diff --git a/test/types/object.js b/test/types/object.js index eb19d3422..cb1a30757 100755 --- a/test/types/object.js +++ b/test/types/object.js @@ -91,7 +91,7 @@ describe('object', () => { it('retains skipped values', () => { const schema = Joi.object({ b: 5 }).unknown(true); - expect(schema.validate({ b: '5', a: 5 })).to.equal({ value: { a: 5, b: 5 } }); + expect(schema.validate({ b: 5, a: 5 })).to.equal({ value: { a: 5, b: 5 } }); }); it('retains symbols', () => { @@ -1660,7 +1660,7 @@ describe('object', () => { it('overrides existing keys', () => { - const a = Joi.object({ a: 1 }); + const a = Joi.object({ a: Joi.number().valid(1) }); const b = a.keys({ a: Joi.string() }); Helper.validate(a, [