diff --git a/lib/types/symbol/index.js b/lib/types/symbol/index.js index 2a04feab8..df218cf19 100644 --- a/lib/types/symbol/index.js +++ b/lib/types/symbol/index.js @@ -2,6 +2,8 @@ // Load modules +const Util = require('util'); + const Any = require('../any'); const Hoek = require('hoek'); @@ -20,13 +22,7 @@ internals.Map = class extends Map { toString() { - const entries = [...this].map(([key, symbol]) => { - - key = typeof key === 'symbol' ? key.toString() : JSON.stringify(key); - return `${key} => ${symbol.toString()}`; - }); - - return `Map { ${entries.join(', ')} }`; + return Util.inspect(this); } }; @@ -76,7 +72,7 @@ internals.Symbol = class extends Any { Hoek.assert(entry && entry[Symbol.iterator], 'Entry must be an iterable'); const [key, value] = entry; - Hoek.assert(typeof key !== 'object' && typeof key !== 'function', 'Key must be a simple type'); + Hoek.assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be an object, function, or Symbol'); Hoek.assert(typeof value === 'symbol', 'Value must be a Symbol'); obj._inner.map.set(key, value); symbols.push(value); @@ -87,7 +83,7 @@ internals.Symbol = class extends Any { describe() { - const description = Any.prototype.describe.call(this); + const description = super.describe(); description.map = new Map(this._inner.map); return description; } diff --git a/test/types/symbol.js b/test/types/symbol.js index 72ed7af31..450340c50 100644 --- a/test/types/symbol.js +++ b/test/types/symbol.js @@ -77,17 +77,17 @@ describe('symbol', () => { it('converts keys to correct symbol', () => { - const symbols = [Symbol(1), Symbol(2), Symbol(3)]; + const symbols = [Symbol(1), Symbol(2)]; const otherSymbol = Symbol(1); - const map = new Map([[1, symbols[0]], ['two', symbols[1]], [symbols[0], symbols[2]]]); + const map = new Map([[1, symbols[0]], ['two', symbols[1]]]); const rule = Joi.symbol().map(map); Helper.validate(rule, [ [1, true, null, symbols[0]], [symbols[0], true, null, symbols[0]], ['1', false, null, { - message: '"value" must be one of Map { 1 => Symbol(1), "two" => Symbol(2), Symbol(1) => Symbol(3) }', + message: `"value" must be one of Map { 1 => Symbol(1), 'two' => Symbol(2) }`, details: [{ - message: '"value" must be one of Map { 1 => Symbol(1), "two" => Symbol(2), Symbol(1) => Symbol(3) }', + message: `"value" must be one of Map { 1 => Symbol(1), 'two' => Symbol(2) }`, path: [], type: 'symbol.map', context: { label: 'value', key: undefined, map } @@ -95,9 +95,9 @@ describe('symbol', () => { }], ['two', true, null, symbols[1]], [otherSymbol, false, null, { - message: '"value" must be one of [Symbol(1), Symbol(2), Symbol(3)]', + message: '"value" must be one of [Symbol(1), Symbol(2)]', details: [{ - message: '"value" must be one of [Symbol(1), Symbol(2), Symbol(3)]', + message: '"value" must be one of [Symbol(1), Symbol(2)]', path: [], type: 'any.allowOnly', context: { value: otherSymbol, label: 'value', valids: symbols, key: undefined } @@ -125,9 +125,9 @@ describe('symbol', () => { }] }], ['toString', false, null, { - message: '"value" must be one of Map { "one" => Symbol(one), "two" => Symbol(two) }', + message: `"value" must be one of Map { 'one' => Symbol(one), 'two' => Symbol(two) }`, details: [{ - message: '"value" must be one of Map { "one" => Symbol(one), "two" => Symbol(two) }', + message: `"value" must be one of Map { 'one' => Symbol(one), 'two' => Symbol(two) }`, path: [], type: 'symbol.map', context: { label: 'value', key: undefined, map: new Map([['one', symbols[0]], ['two', symbols[1]]]) } @@ -180,7 +180,15 @@ describe('symbol', () => { expect( () => Joi.symbol().map([[{}, Symbol()]]) - ).to.throw('Key must be a simple type'); + ).to.throw('Key must not be an object, function, or Symbol'); + + expect( + () => Joi.symbol().map([[() => {}, Symbol()]]) + ).to.throw('Key must not be an object, function, or Symbol'); + + expect( + () => Joi.symbol().map([[Symbol(), Symbol()]]) + ).to.throw('Key must not be an object, function, or Symbol'); }); });