Skip to content

Commit

Permalink
fix: support all cases with one number in range (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
vankop authored and evilebottnawi committed Oct 1, 2019
1 parent 9cf11ad commit 7fc8069
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 52 deletions.
92 changes: 58 additions & 34 deletions src/ValidationError.js
Expand Up @@ -247,6 +247,51 @@ function getSchemaNonTypes(schema) {
return '';
}

function numberHints(schema) {
const hints = [];
const range = new Range();

if (typeof schema.minimum === 'number') {
range.left(schema.minimum);
}

if (typeof schema.exclusiveMinimum === 'number') {
range.left(schema.exclusiveMinimum, true);
}

if (typeof schema.maximum === 'number') {
range.right(schema.maximum);
}

if (typeof schema.exclusiveMaximum === 'number') {
range.right(schema.exclusiveMaximum, true);
}

const rangeFormat = range.format();

if (rangeFormat) {
hints.push(rangeFormat);
}

if (typeof schema.multipleOf === 'number') {
hints.push(`should be multiple of ${schema.multipleOf}`);
}

return hints;
}

function formatHints(hints) {
return hints.length > 0 ? `(${hints.join(', ')})` : '';
}

function getHints(schema) {
if (likeNumber(schema) || likeInteger(schema)) {
return formatHints(numberHints(schema));
}

return '';
}

class ValidationError extends Error {
constructor(errors, schema, configuration = {}) {
super();
Expand Down Expand Up @@ -349,38 +394,10 @@ class ValidationError extends Error {
}

if (likeNumber(schema) || likeInteger(schema)) {
const hints = [];
const range = new Range();

if (typeof schema.minimum === 'number') {
range.left(schema.minimum);
}

if (typeof schema.exclusiveMinimum === 'number') {
range.left(schema.exclusiveMinimum, true);
}

if (typeof schema.maximum === 'number') {
range.right(schema.maximum);
}

if (typeof schema.exclusiveMaximum === 'number') {
range.right(schema.exclusiveMaximum, true);
}

const rangeFormat = range.format();

if (rangeFormat) {
hints.push(rangeFormat);
}

if (typeof schema.multipleOf === 'number') {
hints.push(`should be multiple of ${schema.multipleOf}`);
}

const type = schema.type === 'integer' ? 'integer' : 'number';
const hints = getHints(schema);

return `${type}${hints.length > 0 ? ` (${hints.join(', ')})` : ''}`;
return `${type}${hints.length > 0 ? ` ${hints}` : ''}`;
}

if (likeString(schema)) {
Expand Down Expand Up @@ -743,12 +760,19 @@ class ValidationError extends Error {
case 'minimum':
case 'maximum':
case 'exclusiveMinimum':
case 'exclusiveMaximum':
return `${dataPath} should be ${error.params.comparison} ${
error.params.limit
}${getSchemaNonTypes(
case 'exclusiveMaximum': {
const hints = numberHints(error.parentSchema);

if (hints.length === 0) {
hints.push(
`should be ${error.params.comparison} ${error.params.limit}`
);
}

return `${dataPath} ${hints.join(' ')}${getSchemaNonTypes(
error.parentSchema
)}.${this.getSchemaPartDescription(error.parentSchema)}`;
}
case 'multipleOf':
return `${dataPath} should be multiple of ${
error.params.multipleOf
Expand Down
14 changes: 5 additions & 9 deletions src/util/Range.js
Expand Up @@ -118,16 +118,12 @@ class Range {
return '';
}

if (leftExclusive === rightExclusive) {
// e.g. 5 <= x <= 5
if (leftExclusive === false && start === end) {
return `should be ${logic ? '' : '!'}= ${start}`;
}
const realStart = leftExclusive ? start + 1 : start;
const realEnd = rightExclusive ? end - 1 : end;

// e.g. 4 < x < 6
if (leftExclusive === true && start + 1 === end - 1) {
return `should be ${logic ? '' : '!'}= ${start + 1}`;
}
// e.g. 5 < x < 7, 5 < x <= 6, 6 <= x <= 6
if (realStart === realEnd) {
return `should be ${logic ? '' : '!'}= ${realStart}`;
}

// e.g. 4 < x < ∞
Expand Down
23 changes: 14 additions & 9 deletions test/__snapshots__/index.test.js.snap

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions test/fixtures/schema.json
Expand Up @@ -2925,6 +2925,11 @@
"minLength": 2
}
},
"integerEqualsTo5": {
"type": "integer",
"minimum": 5,
"exclusiveMaximum": 6
},
"integerWithMinimum": {
"type": "integer",
"minimum": 5,
Expand Down
8 changes: 8 additions & 0 deletions test/index.test.js
Expand Up @@ -1639,6 +1639,14 @@ describe('Validation', () => {
(msg) => expect(msg).toMatchSnapshot()
);

createFailedTestCase(
'integer equals to 5',
{
integerEqualsTo5: 6,
},
(msg) => expect(msg).toMatchSnapshot()
);

createFailedTestCase(
'integer with minimum',
{
Expand Down
8 changes: 8 additions & 0 deletions test/range.test.js
Expand Up @@ -16,6 +16,14 @@ it('not 5 <= x <= 5', () => {
expect(range.format(false)).toEqual('should be != 5');
});

it('5 < x <= 6', () => {
const range = new Range();
range.left(5, true);
range.right(6);

expect(range.format()).toEqual('should be = 6');
});

it('-1 < x < 1', () => {
const range = new Range();
range.left(-1, true);
Expand Down

0 comments on commit 7fc8069

Please sign in to comment.