refactored "default" to correctly validate minProperties, minItems, etc. when defaults are present, closes #42

master
Evgeny Poberezkin 2016-01-09 13:28:40 +00:00
parent 94a8f9abb3
commit 8fe96db455
8 changed files with 50 additions and 45 deletions

28
lib/dot/defaults.def Normal file
View File

@ -0,0 +1,28 @@
{{## def.assignDefault:
if ({{=$passData}} === undefined)
{{=$passData}} = {{= it.useDefault($sch.default) }};
#}}
{{## def.defaultProperties:
{{
var $schema = it.schema.properties
, $schemaKeys = Object.keys($schema); }}
{{~ $schemaKeys:$propertyKey }}
{{ var $sch = $schema[$propertyKey]; }}
{{? $sch.default !== undefined }}
{{ var $passData = $data + it.util.getProperty($propertyKey); }}
{{# def.assignDefault }}
{{?}}
{{~}}
#}}
{{## def.defaultItems:
{{~ it.schema.items:$sch:$i }}
{{? $sch.default !== undefined }}
{{ var $passData = $data + '[' + $i + ']'; }}
{{# def.assignDefault }}
{{?}}
{{~}}
#}}

View File

@ -43,21 +43,13 @@ var {{=$valid}};
{{# def.elseIfValid}}
{{?}}
{{ var $useDefaults = it.opts.useDefaults && !it.compositeRule; }}
{{~ $schema:$sch:$i }}
{{ var $passData = $data + '[' + $i + ']'; }}
{{? $useDefaults && $sch.default !== undefined }}
if ({{=$passData}} === undefined)
{{=$passData}} = {{= it.useDefault($sch.default) }};
{{?}}
{{? {{# def.nonEmptySchema:$sch }} }}
valid{{=$it.level}} = true;
if ({{=$data}}.length > {{=$i}}) {
{{
var $passData = $data + '[' + $i + ']';
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errSchemaPath = $errSchemaPath + '/' + $i;

View File

@ -138,19 +138,11 @@ var valid{{=$it.level}} = true;
{{~ $schemaKeys:$propertyKey }}
{{ var $sch = $schema[$propertyKey]; }}
{{
var $prop = it.util.getProperty($propertyKey)
, $passData = $data + $prop
, $hasDefault = $useDefaults && $sch.default !== undefined;
}}
{{? $hasDefault }}
if ({{=$passData}} === undefined)
{{=$passData}} = {{= it.useDefault($sch.default) }};
{{?}}
{{? {{# def.nonEmptySchema:$sch}} }}
{{
var $prop = it.util.getProperty($propertyKey)
, $passData = $data + $prop
, $hasDefault = $useDefaults && $sch.default !== undefined;
$it.schema = $sch;
$it.schemaPath = $schemaPath + $prop;
$it.errSchemaPath = $errSchemaPath + '/' + it.util.escapeFragment($propertyKey);

View File

@ -6,20 +6,10 @@
{{## def.setupLoop:
{{
var $useDefaults = it.opts.useDefaults && !it.compositeRule
, $hasProperties = it.schema.properties !== undefined
, $checkDefaults = $useDefaults && $hasProperties;
}}
{{? !$isData }}
var schema{{=$lvl}} = validate.schema{{=$schemaPath}};
{{?}}
{{? $checkDefaults }}
var propsSchema{{=$lvl}} = validate.schema{{=it.schemaPath}}.properties;
{{?}}
{{
var $i = 'i' + $lvl
, $propertyPath = 'schema' + $lvl + '[' + $i + ']'
@ -31,14 +21,6 @@
#}}
{{## def.checkDefaults:
var property{{=$lvl}} = schema{{=$lvl}}[{{=$i}}];
{{? $checkDefaults }}
if (propsSchema{{=$lvl}}[property{{=$lvl}}].default !== undefined)
continue;
{{?}}
#}}
{{? !$isData }}
{{? $schema.length < it.opts.loopRequired &&
it.schema.properties && Object.keys(it.schema.properties).length }}
@ -70,8 +52,7 @@
{{?$isData}}{{# def.check$dataIsArray }}{{?}}
for (var {{=$i}} = 0; {{=$i}} < schema{{=$lvl}}.length; {{=$i}}++) {
{{# def.checkDefaults }}
{{=$valid}} = {{=$data}}[property{{=$lvl}}] !== undefined;
{{=$valid}} = {{=$data}}[schema{{=$lvl}}[{{=$i}}]] !== undefined;
if (!{{=$valid}}) break;
}
@ -95,7 +76,6 @@
{{?}}
for (var {{=$i}} = 0; {{=$i}} < schema{{=$lvl}}.length; {{=$i}}++) {
{{# def.checkDefaults }}
if ({{=$data}}[schema{{=$lvl}}[{{=$i}}]] === undefined) {
{{# def.addError:'required' }}
}

View File

@ -1,5 +1,6 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.defaults }}
{{ /**
* schema compilation (render) time:
@ -56,6 +57,13 @@
{{? $rulesGroup.type }}
if ({{= it.util.checkDataType($rulesGroup.type, $data) }}) {
{{?}}
{{? it.opts.useDefaults && !it.compositeRule }}
{{? $rulesGroup.type == 'object' && it.schema.properties }}
{{# def.defaultProperties }}
{{?? $rulesGroup.type == 'array' && Array.isArray(it.schema.items) }}
{{# def.defaultItems }}
{{?}}
{{?}}
{{~ $rulesGroup.rules:$rule }}
{{? $shouldUseRule($rule) }}
{{? $rule.custom }}

View File

@ -1,6 +1,6 @@
{
"name": "ajv",
"version": "3.1.1",
"version": "3.2.0",
"description": "Another JSON Schema Validator",
"main": "lib/ajv.js",
"files": [

View File

@ -7,9 +7,12 @@ var glob = require('glob')
, beautify = require('js-beautify').js_beautify;
var defs = {};
['definitions', 'errors', 'custom', 'missing'].forEach(function (name) {
defs[name] = fs.readFileSync(path.join(__dirname, '../lib/dot/' + name + '.def'));
var defFiles = glob.sync('../lib/dot/**/*.def', { cwd: __dirname });
defFiles.forEach(function (f) {
var name = path.basename(f, '.def');
defs[name] = fs.readFileSync(path.join(__dirname, f));
});
var files = glob.sync('../lib/dot/**/*.jst', { cwd: __dirname });
var dotjsPath = path.join(__dirname, '../lib/dotjs');

View File

@ -354,7 +354,8 @@ describe('Ajv Options', function () {
obj: { type: 'object', default: {} },
arr: { type: 'array', default: [] }
},
required: ['foo', 'bar', 'baz', 'nil', 'obj', 'arr']
required: ['foo', 'bar', 'baz', 'nil', 'obj', 'arr'],
minProperties: 6
};
var validate = ajv.compile(schema);
@ -380,6 +381,7 @@ describe('Ajv Options', function () {
{ type: 'number', default: 1 },
{ type: 'boolean', default: false }
],
minItems: 3
};
var validate = ajv.compile(schema);