Skip to content

Commit

Permalink
feat: validate types before other keywords, ajv-validator#485
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed May 13, 2017
1 parent 6f0ff64 commit f60fedb
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 17 deletions.
4 changes: 3 additions & 1 deletion lib/compile/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = function rules() {
];
var TYPES = [ 'number', 'integer', 'string', 'array', 'object', 'boolean', 'null' ];
RULES.all = toHash(ALL);
RULES.types = toHash(TYPES);

RULES.forEach(function (group) {
group.rules = group.rules.map(function (keyword) {
Expand All @@ -46,10 +47,11 @@ module.exports = function rules() {
};
return rule;
});

if (group.type) RULES.types[group.type] = group;
});

RULES.keywords = toHash(ALL.concat(KEYWORDS));
RULES.types = toHash(TYPES);
RULES.custom = {};

return RULES;
Expand Down
44 changes: 28 additions & 16 deletions lib/dot/validate.jst
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@
var $errorKeyword;
var $typeSchema = it.schema.type
, $typeIsArray = Array.isArray($typeSchema);

if ($typeIsArray && $typeSchema.length == 1) {
$typeSchema = $typeSchema[0];
$typeIsArray = false;
}
}}

{{## def.checkType:
Expand All @@ -129,15 +134,6 @@
if ({{= it.util[$method]($typeSchema, $data, true) }}) {
#}}

{{? $typeSchema && it.opts.coerceTypes }}
{{ var $coerceToTypes = it.util.coerceToTypes(it.opts.coerceTypes, $typeSchema); }}
{{? $coerceToTypes }}
{{# def.checkType }}
{{# def.coerceType }}
}
{{?}}
{{?}}

{{? it.schema.$ref && $refKeywords }}
{{? it.opts.extendRefs == 'fail' }}
{{ throw new Error('$ref: validation keywords used in schema at path "' + it.errSchemaPath + '" (see option extendRefs)'); }}
Expand All @@ -149,6 +145,29 @@
{{?}}
{{?}}

{{? $typeSchema }}
{{? it.opts.coerceTypes }}
{{ var $coerceToTypes = it.util.coerceToTypes(it.opts.coerceTypes, $typeSchema); }}
{{?}}

{{ var $rulesGroup = it.RULES.types[$typeSchema]; }}
{{? $coerceToTypes || $typeIsArray || $rulesGroup === true ||
($rulesGroup && !$shouldUseGroup($rulesGroup)) }}
{{
var $schemaPath = it.schemaPath + '.type'
, $errSchemaPath = it.errSchemaPath + '/type';
}}
{{# def.checkType }}
{{? $coerceToTypes }}
{{# def.coerceType }}
{{??}}
{{# def.error:'type' }}
{{?}}
}
{{?}}
{{?}}


{{? it.schema.$ref && !$refKeywords }}
{{= it.RULES.all.$ref.code(it, '$ref') }}
{{? $breakOnError }}
Expand Down Expand Up @@ -190,7 +209,6 @@
{{? $rulesGroup.type }}
}
{{? $typeSchema && $typeSchema === $rulesGroup.type && !$coerceToTypes }}
{{ var $typeChecked = true; }}
else {
{{
var $schemaPath = it.schemaPath + '.type'
Expand All @@ -209,12 +227,6 @@
{{~}}
{{?}}

{{? $typeSchema && !$typeChecked && !$coerceToTypes }}
{{# def.checkType }}
{{# def.error:'type' }}
}
{{?}}

{{? $breakOnError }} {{= $closingBraces2 }} {{?}}

{{? $top }}
Expand Down
28 changes: 28 additions & 0 deletions spec/issues.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -548,3 +548,31 @@ describe('issue #388, code clean-up not working', function() {
should.equal(code.match(/[^\.]errors|vErrors/g), null);
});
});


describe('issue #485, order of type validation', function() {
it('should validate types befor keywords', function() {
var ajv = new Ajv({allErrors: true});
var validate = ajv.compile({
type: ['integer', 'string'],
required: ['foo'],
minimum: 2
});

validate(2) .should.equal(true);
validate('foo') .should.equal(true);

validate(1.5) .should.equal(false);
checkErrors(['type', 'minimum']);

validate({}) .should.equal(false);
checkErrors(['type', 'required']);

function checkErrors(expectedErrs) {
validate.errors .should.have.length(expectedErrs.length);
expectedErrs.forEach(function (keyword, i) {
validate.errors[i].keyword .should.equal(keyword);
});
}
});
});

0 comments on commit f60fedb

Please sign in to comment.