From f94498c05db375e2952f6f5ec29ce5cd2a8ac083 Mon Sep 17 00:00:00 2001 From: Dmitry Maganov Date: Sun, 3 Feb 2019 17:17:07 +0300 Subject: [PATCH] feat: use a schema as when condition --- src/Condition.js | 17 +++++++++++++---- test/mixed.js | 29 ++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/Condition.js b/src/Condition.js index d1ef6eed6..235d4db7d 100644 --- a/src/Condition.js +++ b/src/Condition.js @@ -7,6 +7,10 @@ function callOrConcat(schema) { return base => base.concat(schema); } +function makeIsFn(refs, predicate) { + return refs.length < 2 ? predicate : (...values) => values.every(predicate); +} + class Conditional { constructor(refs, options) { let { is, then, otherwise } = options; @@ -26,10 +30,15 @@ class Conditional { 'either `then:` or `otherwise:` is required for `when()` conditions', ); - let isFn = - typeof is === 'function' - ? is - : (...values) => values.every(value => value === is); + let isFn; + + if (typeof is === 'function') { + isFn = is; + } else if (isSchema(is)) { + isFn = makeIsFn(this.refs, value => is.isValidSync(value)); + } else { + isFn = makeIsFn(this.refs, value => value === is); + } this.fn = function(...values) { let currentSchema = values.pop(); diff --git a/test/mixed.js b/test/mixed.js index 153f79ed3..4ca427791 100644 --- a/test/mixed.js +++ b/test/mixed.js @@ -1,4 +1,15 @@ -import { array, mixed, string, number, object, ref, reach, bool } from '../src'; +import { + array, + mixed, + string, + number, + object, + ref, + reach, + bool, + boolean, + ValidationError, +} from '../src'; let noop = () => {}; function ensureSync(fn) { @@ -701,6 +712,22 @@ describe('Mixed Types ', () => { inst.default().should.eql({ prop: undefined }); }); + it('should handle conditionals with schema as condition', async function() { + let inst = object({ + flag: mixed(), + prop: number().when('flag', { + is: boolean(), + then: number().min(5), + }), + }); + + await inst.validate({ flag: 'hello', prop: 4 }).should.be.fulfilled(); + + await inst + .validate({ flag: true, prop: 4 }) + .should.be.rejectedWith(ValidationError, /must be greater than/); + }); + it('should use label in error message', async function() { let label = 'Label'; let inst = object({