diff --git a/src/mixed.js b/src/mixed.js index f99cdfa7d..d6f67b952 100644 --- a/src/mixed.js +++ b/src/mixed.js @@ -1,4 +1,3 @@ -import typeOf from 'type-name'; import has from 'lodash/has'; import { mixed as locale } from './locale'; @@ -133,15 +132,23 @@ SchemaType.prototype = { return this }, - cast(value, opts = {}) { - let schema = this.resolve(opts) - - let result = schema._cast(value, opts); - - if (opts.assert !== false && !this.isType(result)) { + cast(value, options = {}) { + let resolvedSchema = this.resolve(options) + let result = resolvedSchema._cast(value, options); + + if ( + value !== undefined && + options.assert !== false && + resolvedSchema.isType(result) !== true + ) { + let formattedValue = JSON.stringify(value); + let formattedResult = JSON.stringify(result); throw new TypeError( - `Expected ${opts.path || 'field'} to be type: "${this._type}". ` + - `Got "${typeOf(value)}" instead.` + `The value of ${options.path || 'field'} could not be cast to a value ` + + `that satisfies the schema type: "${resolvedSchema._type}". \n\n` + + `attempted value: ${JSON.stringify(value)} \n` + + ((formattedResult !== formattedValue) + ? `result of cast: ${JSON.stringify(result)}` : '') ); } diff --git a/test/helpers.js b/test/helpers.js index d2c98d14e..ea2cb955a 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,10 +1,9 @@ -import typeOf from 'type-name'; export let castAndShouldFail = (schema, value) => { (()=> schema.cast(value)) .should.throw( TypeError, - new RegExp(`Got "${typeOf(value)}" instead`, 'gi') + /The value of (.+) could not be cast to a value that satisfies the schema type/gi ) } diff --git a/test/string.js b/test/string.js index 91407ac07..6964a336c 100644 --- a/test/string.js +++ b/test/string.js @@ -19,7 +19,6 @@ describe('String types', function(){ [null, null, schema.nullable()] ], invalid: [ - undefined, null, ] }) diff --git a/test/yup.js b/test/yup.js index f4e1d8381..a78be23cf 100644 --- a/test/yup.js +++ b/test/yup.js @@ -12,6 +12,24 @@ describe('Yup', function(){ require('../lib') }) + it('cast should not assert on undefined', () => { + (() => string().cast(undefined)) + .should.not.throw() + }) + + it('cast should assert on undefined cast results', () => { + (() => string().transform(() => undefined).cast('foo')) + .should.throw() + }) + + it('cast should respect assert option', () => { + (() => string().cast(null)) + .should.throw(); + + (() => string().cast(null, { assert: false })) + .should.not.throw() + }) + it('should do settled', function(){ return Promise.all([