Skip to content

Commit

Permalink
feat: finalize resolve()
Browse files Browse the repository at this point in the history
  • Loading branch information
vonagam committed Feb 5, 2019
1 parent d02ff5e commit 9f7d85e
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 47 deletions.
25 changes: 13 additions & 12 deletions src/Condition.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import isSchema from './util/isSchema';

function callOrConcat(schema) {
if (typeof schema === 'function') return schema;

return base => base.concat(schema);
if (!schema) return base => base;
return (base, options) => base.concat(schema.resolve(options));
}

class Conditional {
Expand Down Expand Up @@ -32,27 +32,28 @@ class Conditional {
: (...values) => values.every(value => value === is);

this.fn = function(...values) {
let currentSchema = values.pop();
let options = values.pop();
let schema = values.pop();
let option = isFn(...values) ? then : otherwise;

return option(currentSchema);
return option(schema, options);
};
}
}

getValue(parent, context) {
let values = this.refs.map(r => r.getValue(parent, context));
resolve(ctx, options) {
let values = this.refs.map(r =>
r.getValue(options.parent, options.context),
);

return values;
}
let schema = this.fn.apply(ctx, values.concat(ctx, options));

resolve(ctx, values) {
let schema = this.fn.apply(ctx, values.concat(ctx));
if (schema === undefined) return ctx;

if (schema !== undefined && !isSchema(schema))
if (!isSchema(schema))
throw new TypeError('conditions must return a schema object');

return schema || ctx;
return schema.resolve(options);
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/Lazy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ import isSchema from './util/isSchema';

class Lazy {
constructor(mapFn) {
this._resolve = (...args) => {
let schema = mapFn(...args);
this._resolve = (value, options) => {
let schema = mapFn(value, options);

if (!isSchema(schema))
throw new TypeError('lazy() functions must return a valid schema');

return schema;
return schema.resolve(options);
};
}
resolve({ value, ...rest }) {
return this._resolve(value, rest);
resolve(options) {
return this._resolve(options.value, options);
}
cast(value, options) {
return this._resolve(value, options).cast(value, options);
Expand Down
19 changes: 12 additions & 7 deletions src/mixed.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,21 @@ const proto = (SchemaType.prototype = {
return !this._typeCheck || this._typeCheck(v);
},

resolve({ context, parent }) {
if (this._conditions.length) {
return this._conditions.reduce(
(schema, match) =>
match.resolve(schema, match.getValue(parent, context)),
this,
resolve(options) {
let schema = this;

while (schema._conditions.length) {
let conditions = schema._conditions;

schema = schema.clone();
schema._conditions = [];
schema = conditions.reduce(
(schema, condition) => condition.resolve(schema, options),
schema,
);
}

return this;
return schema;
},

cast(value, options = {}) {
Expand Down
6 changes: 1 addition & 5 deletions src/util/reach.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function getIn(schema, path, value, context) {
return {
parent,
parentPath: path,
schema: schema.resolve({ context, parent, value }),
schema,
};

forEach(path, (_part, isBracket, isArray) => {
Expand Down Expand Up @@ -55,10 +55,6 @@ export function getIn(schema, path, value, context) {
}
});

if (schema) {
schema = schema.resolve({ context, parent, value });
}

return { schema, parent, parentPath: lastPart };
}

Expand Down
36 changes: 35 additions & 1 deletion test/mixed.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import { array, mixed, string, number, object, ref, reach, bool } from '../src';
import {
array,
mixed,
string,
number,
object,
ref,
reach,
bool,
lazy,
ValidationError,
} from '../src';

let noop = () => {};

function ensureSync(fn) {
Expand Down Expand Up @@ -701,6 +713,28 @@ describe('Mixed Types ', () => {
inst.default().should.eql({ prop: undefined });
});

it('should allow nested conditions and lazies', async function() {
let inst = string().when('$check', {
is: value => typeof value === 'string',
then: string().when('$check', {
is: value => /hello/.test(value),
then: lazy(() => string().min(6)),
}),
});

await inst
.validate('pass', { context: { check: false } })
.should.be.fulfilled();

await inst
.validate('pass', { context: { check: 'hello' } })
.should.be.rejectedWith(ValidationError, /must be at least/);

await inst
.validate('passes', { context: { check: 'hello' } })
.should.be.fulfilled();
});

it('should use label in error message', async function() {
let label = 'Label';
let inst = object({
Expand Down
4 changes: 2 additions & 2 deletions test/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,8 @@ describe('Object types', () => {
}),
});

reach(inst, 'nested').should.equal(inst);
reach(inst, 'x.y').should.equal(inst);
reach(inst, 'nested').should.equal(inst.fields.nested);
reach(inst, 'x.y').should.equal(inst.fields.x.fields.y);
});

it('should be passed the value', done => {
Expand Down
33 changes: 18 additions & 15 deletions test/yup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import reach, { getIn } from '../src/util/reach';
import merge from '../src/util/merge';
import { settled } from '../src/util/runValidations';

import { object, array, string, lazy, number } from '../src';
import { object, array, string, lazy, number, ValidationError } from '../src';

describe('Yup', function() {
it('cast should not assert on undefined', () => {
Expand Down Expand Up @@ -97,8 +97,8 @@ describe('Yup', function() {
valid.should.equal(true);
});

it('should REACH conditionally correctly', function() {
var num = number(),
it('should REACH conditionally correctly', async function() {
var num = number().oneOf([4]),
inst = object().shape({
num: number().max(4),
nested: object().shape({
Expand All @@ -125,21 +125,24 @@ describe('Yup', function() {
},
};

reach(inst, 'nested.arr.num', value).should.equal(num);
reach(inst, 'nested.arr[].num', value).should.equal(num);
// reach(inst, 'nested.arr.num', value).should.equal(num);
// reach(inst, 'nested.arr[].num', value).should.equal(num);

reach(inst, 'nested.arr.num', value, context).should.equal(num);
reach(inst, 'nested.arr[].num', value, context).should.equal(num);
reach(inst, 'nested.arr[0].num', value, context).should.equal(num);
// reach(inst, 'nested.arr.num', value, context).should.equal(num);
// reach(inst, 'nested.arr[].num', value, context).should.equal(num);
// reach(inst, 'nested.arr[0].num', value, context).should.equal(num);

// should fail b/c item[1] is used to resolve the schema
reach(inst, 'nested["arr"][1].num', value, context).should.not.equal(num);
// // should fail b/c item[1] is used to resolve the schema
// reach(inst, 'nested["arr"][1].num', value, context).should.not.equal(num);

return reach(inst, 'nested.arr[].num', value, context)
.isValid(5)
.then(valid => {
valid.should.equal(true);
});
let reached = reach(inst, 'nested.arr[].num', value, context);

await reached.validate(5, { context, parent: { foo: 4 } }).should.be
.fulfilled;

await reached
.validate(5, { context, parent: { foo: 5 } })
.should.be.rejectedWith(ValidationError, /one of the following/);
});

it('should reach through lazy', async () => {
Expand Down

0 comments on commit 9f7d85e

Please sign in to comment.