From 0f4312264d23f24183cc7adf2dfe82232c477916 Mon Sep 17 00:00:00 2001 From: Jason Quense Date: Tue, 19 Jul 2016 22:00:38 -0400 Subject: [PATCH] [chore] clean up code --- src/array.js | 15 +++------------ src/mixed.js | 45 ++++++++++++++++++++++---------------------- src/util/makePath.js | 9 +++++++++ test/mixed.js | 26 ++++++++++++++----------- test/object.js | 2 +- test/yup.js | 30 ----------------------------- 6 files changed, 50 insertions(+), 77 deletions(-) create mode 100644 src/util/makePath.js diff --git a/src/array.js b/src/array.js index 0ceb91d..6379414 100644 --- a/src/array.js +++ b/src/array.js @@ -3,6 +3,7 @@ import typeOf from 'type-name'; import inherits from './util/inherits'; import isAbsent from './util/isAbsent'; import isSchema from './util/isSchema'; +import makePath from './util/makePath'; import MixedSchema from './mixed'; import { mixed, array as locale } from './locale.js'; import runValidations, { propagateErrors } from './util/runValidations'; @@ -70,7 +71,7 @@ inherits(ArraySchema, MixedSchema, { } let validations = value.map((item, idx) => { - var path = (options.path || '') + '[' + idx + ']' + var path = makePath`${options.path}[${idx}]` // object._validate note for isStrict explanation var innerOptions = { @@ -96,23 +97,13 @@ inherits(ArraySchema, MixedSchema, { }) }, - // concat(schema) { - // var next = MixedSchema.prototype.concat.call(this, schema) - // - // next._subType = schema._subType === undefined - // ? this._subType - // : schema._subType; - // - // return next - // }, - of(schema) { var next = this.clone() if (schema !== false && !isSchema(schema)) throw new TypeError( '`array.of()` sub-schema must be a valid yup schema, or `false` to negate a current sub-schema. ' + - 'got: ' + typeOf(schema) + ' instead' + 'not: ' + typeOf(schema) ) next._subType = schema; diff --git a/src/mixed.js b/src/mixed.js index d6f67b9..2abe618 100644 --- a/src/mixed.js +++ b/src/mixed.js @@ -155,12 +155,12 @@ SchemaType.prototype = { return result; }, - _cast(_value) { - let value = _value === undefined ? _value + _cast(rawValue) { + let value = rawValue === undefined ? rawValue : this.transforms.reduce( - (value, transform) => transform.call(this, value, _value), _value) + (value, fn) => fn.call(this, value, rawValue), rawValue) - if (value === undefined && (has(this, '_default'))) { + if (value === undefined && has(this, '_default')) { value = this.default() } @@ -176,26 +176,24 @@ SchemaType.prototype = { return nodeify(schema._validate(value, options), cb) }, - //-- tests _validate(_value, options = {}) { - let value = _value - , schema, endEarly, isStrict; + let value = _value; - schema = this - isStrict = this._option('strict', options) - endEarly = this._option('abortEarly', options) + let isStrict = this._option('strict', options) + let endEarly = this._option('abortEarly', options) let path = options.path let label = this._label if (!isStrict) { + value = this._cast(value, { assert: false, ...options }) } // value is cast, we can check if it meets type requirements let validationParams = { value, path, schema: this, options, label } let initialTests = [] - if (schema._typeError) + if (this._typeError) initialTests.push(this._typeError(validationParams)); if (this._whitelistError) @@ -235,9 +233,13 @@ SchemaType.prototype = { default(def) { if (arguments.length === 0) { - var dflt = has(this, '_default') ? this._default : this._defaultDefault - return typeof dflt === 'function' - ? dflt.call(this) : cloneDeep(dflt) + var defaultValue = has(this, '_default') + ? this._default + : this._defaultDefault + + return typeof defaultValue === 'function' + ? defaultValue.call(this) + : cloneDeep(defaultValue) } var next = this.clone() @@ -285,18 +287,18 @@ SchemaType.prototype = { * the previous tests are removed and further tests of the same name will replace each other. */ test(name, message, test, useCallback) { - var opts = extractTestParams(name, message, test, useCallback) + let opts = extractTestParams(name, message, test, useCallback) , next = this.clone(); - var validate = createValidation(opts); + let validate = createValidation(opts); - var isExclusive = ( + let isExclusive = ( opts.exclusive || (opts.name && next._exclusive[opts.name] === true) ) if (opts.exclusive && !opts.name) { - throw new TypeError('You cannot have an exclusive validation without a `name`') + throw new TypeError('Exclusive tests must provide a unique `name` identifying the test') } next._exclusive[opts.name] = !!opts.exclusive @@ -333,8 +335,8 @@ SchemaType.prototype = { var next = this.clone() next._typeError = createValidation({ - message, name: 'typeError', + message, test(value) { if (value !== undefined && !this.schema.isType(value)) return this.createError({ @@ -351,9 +353,6 @@ SchemaType.prototype = { oneOf(enums, message = locale.oneOf) { var next = this.clone(); - if (next.tests.length) - throw new TypeError('Cannot specify values when there are validation rules specified') - enums.forEach(val => { next._blacklist.delete(val) next._whitelist.add(val) @@ -439,7 +438,7 @@ Object.keys(aliases).forEach(method => { }) function nodeify(promise, cb){ - if(typeof cb !== 'function') return promise + if (typeof cb !== 'function') return promise promise.then( val => cb(null, val), diff --git a/src/util/makePath.js b/src/util/makePath.js new file mode 100644 index 0000000..c4567c1 --- /dev/null +++ b/src/util/makePath.js @@ -0,0 +1,9 @@ + +export default function makePath(strings, ...values) { + let path = strings.reduce((str, next) => { + let value = values.shift(); + return str + (value == null ? '' : value) + next + }) + + return path.replace(/^\./, ''); +} diff --git a/test/mixed.js b/test/mixed.js index 3467e55..6a09576 100644 --- a/test/mixed.js +++ b/test/mixed.js @@ -28,10 +28,10 @@ describe( 'Mixed Types ', function(){ ]) }) - it('cast should return a default is empty', function(){ + it('cast should return a default when undefined', function(){ var inst = mixed().default('hello') - return inst.cast().should.equal('hello') + return inst.cast(undefined).should.equal('hello') }) it('should check types', async function(){ @@ -235,7 +235,8 @@ describe( 'Mixed Types ', function(){ .isValid(8).should.eventually.become(true) }) - it('tests should be called with the correct `this`', function(done){ + it('tests should be called with the correct `this`', async () => { + let called = false; var inst = object({ other: mixed(), test: mixed().test({ @@ -246,12 +247,15 @@ describe( 'Mixed Types ', function(){ this.path.should.equal('test') this.parent.should.eql({ other: 5, test: 'hi' }) this.options.context.should.eql({ user: 'jason' }) - done() + called = true; + return true; } }) }) - inst.validate({ other: 5, test: 'hi' }, { context: { user: 'jason' } }) + await inst.validate({ other: 5, test: 'hi' }, { context: { user: 'jason' } }) + + called.should.equal(true) }) it('tests can return an error', function(){ @@ -290,13 +294,13 @@ describe( 'Mixed Types ', function(){ it('should allow custom validation of either style', function(){ var inst = string() - .test('name', 'test a', function(val){ - return Promise.resolve(val === 'jim') - }) - .test('name', 'test b', function(val, done){ - process.nextTick(function(){ + .test('name', 'test a', val => + Promise.resolve(val === 'jim') + ) + .test('name', 'test b', (val, done) => { + process.nextTick(() => done(null, val !== 'jim') - }) + ) }, true) return Promise.all([ diff --git a/test/object.js b/test/object.js index f54fa89..332fb96 100644 --- a/test/object.js +++ b/test/object.js @@ -663,7 +663,7 @@ describe('Object types', function(){ it('should camelCase with leading underscore', function(){ var inst = object().camelcase() - + inst .cast({ CON_STAT: 5, __isNew: true, __IS_FUN: true }) .should diff --git a/test/yup.js b/test/yup.js index a78be23..374eae5 100644 --- a/test/yup.js +++ b/test/yup.js @@ -281,34 +281,4 @@ describe('Yup', function(){ set.values().should.eql([2]) }) }) - - // it.only('should REACH with conditions', function(){ - // var num = number() - // var altShape = { - // next: object().shape({ - // greet: bool(), - // prop: number().when('greet', { is: true, then: number().max(5) }) - // }) - // } - - // var inst = object().shape({ - // num: number().max(4), - // nested: object() - // .when('num', { is: number().min(3), then: object(altShape) }) - // .shape({ - // next: object().shape({ prop: bool() }) - // }) - // }) - - // reach(inst, 'nested.arr[].num', { num: 1 }).should.equal(num) - - // // reach(inst, 'nested.arr[1].num').should.equal(num) - // // reach(inst, 'nested.arr[1].num').should.not.equal(number()) - - // // reach(inst, 'nested.arr[].num').isValid(5, function(err, valid){ - // // valid.should.equal(true) - // // done() - // // }) - // }) - })