Skip to content

Commit

Permalink
Merge branch 'master' into greenkeeper/initial
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed May 18, 2017
2 parents 4b7e422 + a454569 commit f3abd13
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 20 deletions.
4 changes: 3 additions & 1 deletion lib/compile/rules.js
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
50 changes: 32 additions & 18 deletions lib/dot/validate.jst
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,30 @@
{{?}}
{{?}}

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

{{ var $rulesGroup; }}
{{? $coerceToTypes || $typeIsArray ||
($rulesGroup = it.RULES.types[$typeSchema == 'integer' ? 'number' : $typeSchema],
$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 All @@ -163,7 +183,8 @@
{{~ it.RULES:$rulesGroup }}
{{? $shouldUseGroup($rulesGroup) }}
{{? $rulesGroup.type }}
if ({{= it.util.checkDataType($rulesGroup.type, $data) }}) {
{{ var $typeToCheck = $rulesGroup.type == 'number' && $typeSchema == 'integer' ? 'integer' : $rulesGroup.type; }}
if ({{= it.util.checkDataType($typeToCheck, $data) }}) {
{{?}}
{{? it.opts.useDefaults && !it.compositeRule }}
{{? $rulesGroup.type == 'object' && it.schema.properties }}
Expand All @@ -189,8 +210,7 @@
{{?}}
{{? $rulesGroup.type }}
}
{{? $typeSchema && $typeSchema === $rulesGroup.type && !$coerceToTypes }}
{{ var $typeChecked = true; }}
{{? $typeSchema && $typeSchema === $typeToCheck && !$coerceToTypes }}
else {
{{
var $schemaPath = it.schemaPath + '.type'
Expand All @@ -209,12 +229,6 @@
{{~}}
{{?}}

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

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

{{? $top }}
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "ajv",
"version": "5.0.1",
"version": "5.1.1",
"description": "Another JSON Schema Validator",
"main": "lib/ajv.js",
"typings": "lib/ajv.d.ts",
Expand Down
38 changes: 38 additions & 0 deletions spec/issues.spec.js
Expand Up @@ -548,3 +548,41 @@ 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);
});
}
});

it('should validate type only once when "type" is "integer"', function() {
var ajv = new Ajv;
var validate = ajv.compile({
type: 'integer',
minimum: 2
});
var code = validate.toString();
code.match(/typeof\s+/g) .should.have.length(1);
});
});
31 changes: 31 additions & 0 deletions spec/tests/issues/490_integer_validation.json
@@ -0,0 +1,31 @@
[
{
"description": "integer validation (#490)",
"schema": {
"type": "integer",
"minimum": 0
},
"tests": [
{
"description": "valid integer",
"data": 1,
"valid": true
},
{
"description": "invalid integer",
"data": -1,
"valid": false
},
{
"description": "non-integer number is invalid",
"data": 1.1,
"valid": false
},
{
"description": "string is invalid",
"data": "foo",
"valid": false
}
]
}
]

0 comments on commit f3abd13

Please sign in to comment.