diff --git a/index.js b/index.js index 379f2a98..3fdac9a4 100644 --- a/index.js +++ b/index.js @@ -901,7 +901,17 @@ function buildValue (location, input) { switch (type) { case 'string': { code += ` - ${statement}(${input} === null || typeof ${input} === "${type}" || ${input} instanceof RegExp || (typeof ${input} === "object" && Object.prototype.hasOwnProperty.call(${input}, "toString"))) + ${statement}( + typeof ${input} === "string" || + ${input} === null || + ${input} instanceof RegExp || + ( + typeof ${input} === "object" && + typeof ${input}.toString === "function" && + ${input}.toString !== Object.prototype.toString && + !(${input} instanceof Date) + ) + ) ${nestedResult} ` break diff --git a/test/typesArray.test.js b/test/typesArray.test.js index fa840fdf..c6631a03 100644 --- a/test/typesArray.test.js +++ b/test/typesArray.test.js @@ -438,6 +438,35 @@ test('object that is simultaneously a string and a json switched', (t) => { t.equal(valueObj, '{"simultaneously":{"foo":"hello"}}') }) +test('class instance that is simultaneously a string and a json', (t) => { + t.plan(2) + + const schema = { + type: 'object', + properties: { + simultaneously: { + type: ['string', 'object'], + properties: { + foo: { type: 'string' } + } + } + } + } + + class Test { + toString () { return 'hello' } + } + + const likeObjectId = new Test() + + const stringify = build(schema) + const valueStr = stringify({ simultaneously: likeObjectId }) + t.equal(valueStr, '{"simultaneously":"hello"}') + + const valueObj = stringify({ simultaneously: { foo: likeObjectId } }) + t.equal(valueObj, '{"simultaneously":{"foo":"hello"}}') +}) + test('should throw an error when type is array and object is null', (t) => { t.plan(1) const schema = {