Skip to content

Commit 9f6fb73

Browse files
committed
Fix all references usages. Fixes #1030.
1 parent 3841154 commit 9f6fb73

File tree

8 files changed

+111
-5
lines changed

8 files changed

+111
-5
lines changed

lib/alternatives.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ internals.Alternatives = class extends Any {
3333
const item = this._inner.matches[i];
3434
const schema = item.schema;
3535
if (!schema) {
36-
const failed = item.is._validate(item.ref(state.parent, options), null, options, state.parent).errors;
36+
const failed = item.is._validate(item.ref(state.reference || state.parent, options), null, options, state.parent).errors;
3737

3838
if (failed) {
3939
if (item.otherwise) {

lib/date.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ internals.compare = function (type, compare) {
163163
compareTo = Date.now();
164164
}
165165
else if (isRef) {
166-
compareTo = internals.Date.toDate(date(state.parent, options));
166+
compareTo = internals.Date.toDate(date(state.reference || state.parent, options));
167167

168168
if (!compareTo) {
169169
return this.createError('date.ref', { ref: date.key }, state, options);

lib/number.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ internals.Number = class extends Any {
6262

6363
return this._test('multiple', base, function (value, state, options) {
6464

65-
const divisor = isRef ? base(state.parent, options) : base;
65+
const divisor = isRef ? base(state.reference || state.parent, options) : base;
6666

6767
if (isRef && (typeof divisor !== 'number' || !isFinite(divisor))) {
6868
return this.createError('number.ref', { ref: base.key }, state, options);
@@ -144,7 +144,7 @@ internals.compare = function (type, compare) {
144144

145145
let compareTo;
146146
if (isRef) {
147-
compareTo = limit(state.parent, options);
147+
compareTo = limit(state.reference || state.parent, options);
148148

149149
if (!(typeof compareTo === 'number' && !isNaN(compareTo))) {
150150
return this.createError('number.ref', { ref: limit.key }, state, options);

lib/string.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ internals.compare = function (type, compare) {
504504

505505
let compareTo;
506506
if (isRef) {
507-
compareTo = limit(state.parent, options);
507+
compareTo = limit(state.reference || state.parent, options);
508508

509509
if (!Hoek.isInteger(compareTo)) {
510510
return this.createError('string.ref', { ref: limit.key }, state, options);

test/alternatives.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,35 @@ describe('alternatives', () => {
281281
[{ b: 5 }, false, null, 'child "a" fails because ["a" is required]']
282282
], done);
283283
});
284+
285+
it('validates with nested whens', (done) => {
286+
287+
// If ((b === 0 && a === 123) ||
288+
// (b !== 0 && a === anything))
289+
// then c === 456
290+
// else c === 789
291+
const schema = Joi.object({
292+
a: Joi.number().required(),
293+
b: Joi.number().required(),
294+
c: Joi.when('a', {
295+
is: Joi.when('b', {
296+
is: Joi.valid(0),
297+
then: Joi.valid(123)
298+
}),
299+
then: Joi.valid(456),
300+
otherwise: Joi.valid(789)
301+
})
302+
});
303+
304+
Helper.validate(schema, [
305+
[{ a: 123, b: 0, c: 456 }, true],
306+
[{ a: 0, b: 1, c: 456 }, true],
307+
[{ a: 0, b: 0, c: 789 }, true],
308+
[{ a: 123, b: 456, c: 456 }, true],
309+
[{ a: 0, b: 0, c: 456 }, false, null, 'child "c" fails because ["c" must be one of [789]]'],
310+
[{ a: 123, b: 456, c: 789 }, false, null, 'child "c" fails because ["c" must be one of [456]]']
311+
], done);
312+
});
284313
});
285314

286315
describe('describe()', () => {

test/date.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,26 @@ describe('date', () => {
135135
], done);
136136
});
137137

138+
it('accepts references as min date within a when', (done) => {
139+
140+
const schema = Joi.object({
141+
a: Joi.date().required(),
142+
b: Joi.date().required(),
143+
c: Joi.number().required().when('a', {
144+
is: Joi.date().min(Joi.ref('b')), // a >= b
145+
then: Joi.number().valid(0)
146+
})
147+
});
148+
149+
Helper.validate(schema, [
150+
[{ a: 123, b: 123, c: 0 }, true],
151+
[{ a: 123, b: 456, c: 42 }, true],
152+
[{ a: 456, b: 123, c: 0 }, true],
153+
[{ a: 123, b: 123, c: 42 }, false, null, 'child "c" fails because ["c" must be one of [0]]'],
154+
[{ a: 456, b: 123, c: 42 }, false, null, 'child "c" fails because ["c" must be one of [0]]']
155+
], done);
156+
});
157+
138158
it('accepts context references as min date', (done) => {
139159

140160
const schema = Joi.object({ b: Joi.date().min(Joi.ref('$a')) });

test/number.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,26 @@ describe('number', () => {
553553
], done);
554554
});
555555

556+
it('accepts references as min value within a when', (done) => {
557+
558+
const schema = Joi.object({
559+
a: Joi.number().required(),
560+
b: Joi.number().required(),
561+
c: Joi.number().required().when('a', {
562+
is: Joi.number().min(Joi.ref('b')), // a >= b
563+
then: Joi.number().valid(0)
564+
})
565+
});
566+
567+
Helper.validate(schema, [
568+
[{ a: 0, b: 1, c: 42 }, true],
569+
[{ a: 1, b: 1, c: 0 }, true],
570+
[{ a: 2, b: 1, c: 0 }, true],
571+
[{ a: 1, b: 1, c: 42 }, false, null, 'child "c" fails because ["c" must be one of [0]]'],
572+
[{ a: 2, b: 1, c: 42 }, false, null, 'child "c" fails because ["c" must be one of [0]]']
573+
], done);
574+
});
575+
556576
it('accepts context references as min value', (done) => {
557577

558578
const schema = Joi.object({ b: Joi.number().min(Joi.ref('$a')) });
@@ -859,6 +879,25 @@ describe('number', () => {
859879
], done);
860880
});
861881

882+
it('should handle references correctly within a when', (done) => {
883+
884+
const schema = Joi.object({
885+
a: Joi.number().required(),
886+
b: Joi.number().required(),
887+
c: Joi.number().required().when('a', {
888+
is: Joi.number().multiple(Joi.ref('b')), // a % b === 0
889+
then: Joi.number().valid(0)
890+
})
891+
});
892+
893+
Helper.validate(schema, [
894+
[{ a: 2, b: 3, c: 42 }, true],
895+
[{ a: 2, b: 4, c: 42 }, true],
896+
[{ a: 4, b: 2, c: 0 }, true],
897+
[{ a: 4, b: 2, c: 42 }, false, null, 'child "c" fails because ["c" must be one of [0]]']
898+
], done);
899+
});
900+
862901
it('should handle non-number references correctly', (done) => {
863902

864903
const schema = Joi.object({ a: Joi.string(), b: Joi.number().multiple(Joi.ref('a')) });

test/string.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,24 @@ describe('string', () => {
149149
], done);
150150
});
151151

152+
it('accepts references as min length within a when', (done) => {
153+
154+
const schema = Joi.object({
155+
a: Joi.string().required(),
156+
b: Joi.number().required(),
157+
c: Joi.number().required().when('a', {
158+
is: Joi.string().min(Joi.ref('b')), // a.length >= b
159+
then: Joi.number().valid(0)
160+
})
161+
});
162+
163+
Helper.validate(schema, [
164+
[{ a: 'abc', b: 4, c: 42 }, true],
165+
[{ a: 'abc', b: 3, c: 0 }, true],
166+
[{ a: 'abc', b: 3, c: 42 }, false, null, 'child "c" fails because ["c" must be one of [0]]']
167+
], done);
168+
});
169+
152170
it('accepts context references as min length', (done) => {
153171

154172
const schema = Joi.object({ b: Joi.string().min(Joi.ref('$a'), 'utf8') });

0 commit comments

Comments
 (0)