Skip to content

Commit

Permalink
[added] withMutation() method
Browse files Browse the repository at this point in the history
  • Loading branch information
jquense committed Jan 12, 2016
1 parent ad4390c commit 069c6fd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 14 deletions.
40 changes: 26 additions & 14 deletions src/mixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,20 @@ SchemaType.prototype = {

constructor: SchemaType,

clone(){
clone() {
if (this._mutate)
return this;

return cloneDeep(this);
},

withMutation(fn) {
this._mutate = true
let result = fn(this)
this._mutate = false
return result
},

concat(schema){
if (!schema)
return this
Expand Down Expand Up @@ -79,26 +89,28 @@ SchemaType.prototype = {
: this.transforms.reduce(
(value, transform) => transform.call(this, value, _value), _value)


if( value === undefined && _.has(this, '_default') )
if (value === undefined && _.has(this, '_default'))
value = this.default()

return value
},

_resolve(context, parent){
var schema = this;
if (this._deps.length) {
return this._deps.reduce((schema, match) =>
match.resolve(schema, match.getValue(parent, context)), this)
}

return this._deps.reduce((schema, match) =>
match.resolve(schema, match.getValue(parent, context)), schema)
return this
},

//-- tests
_validate(value, options = {}, state = {}) {
_validate(_value, options = {}, state = {}) {
let valids = this._whitelist
, invalids = this._blacklist
, context = options.context
, parent = state.parent
, value = _value
, schema, endEarly, isStrict;

schema = this._resolve(context, parent)
Expand All @@ -110,29 +122,29 @@ SchemaType.prototype = {
let errors = [];
let reject = () => Promise.reject(new ValidationError(errors, value));

if ( !state.isCast && !isStrict )
if (!state.isCast && !isStrict)
value = schema._cast(value, options)

// value is cast, we can check if it meets type requirements
if ( value !== undefined && !schema.isType(value) ){
if (value !== undefined && !schema.isType(value)) {
errors.push(schema._typeError({ value, path, type: schema._type }))
if ( endEarly ) return reject()
}

// next check Whitelist for matching values
if ( valids.length && !valids.has(value) ) {
if (valids.length && !valids.has(value)) {
errors.push(schema._whitelistError(valids.values(), path))
if ( endEarly ) return reject()
if (endEarly) return reject()
}

// next check Blacklist for matching values
if ( invalids.has(value) ){
if (invalids.has(value)) {
errors.push(schema._blacklistError(invalids.values(), path))
if ( endEarly ) return reject()
if (endEarly) return reject()
}

// It makes no sense to validate further at this point if their are errors
if ( errors.length )
if (errors.length)
return reject()

let result = schema.tests.map(fn => fn({ value, path, state, schema, options }))
Expand Down
4 changes: 4 additions & 0 deletions test/mixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ describe( 'Mixed Types ', function(){

it('should be immutable', function(){
var inst = mixed(), next;
var sub = inst.sub = mixed()

inst.should.not.equal(next = inst.required())

next.sub.should.equal(sub)
inst.sub.should.equal(next.sub)

inst.should.be.an.instanceOf(mixed)
next.should.be.an.instanceOf(mixed)

Expand Down
35 changes: 35 additions & 0 deletions test/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,41 @@ describe('Object types', function(){
})
})

it('should not clone during validating', function(){
var inst = object().shape({
num: number().max(4),
str: string(),
arr: array().of(number().max(6)),
dte: date(),

nested: object()
.shape({ str: string().min(3) })
.required(),

arrNested: array().of(
object().shape({ num: number() })
)
})

let base = mixed.prototype.clone;
let replace = () => mixed.prototype.clone = base
mixed.prototype.clone = function(...args) {
if (!this._mutate)
throw new Error('should not call clone')

return base.apply(this, args)
}

return inst
.validate({
nested: { str: 5 },
arrNested: [{ num: 5 }, { num: '2' }]
})
.then(replace)
.catch(replace)
})


it('should call shape with constructed with an arg', function(){
var inst = object({
prop: mixed()
Expand Down

0 comments on commit 069c6fd

Please sign in to comment.