Skip to content

Commit

Permalink
refactored "default" to correctly validate minProperties, minItems, e…
Browse files Browse the repository at this point in the history
…tc. when defaults are present, closes #42
  • Loading branch information
epoberezkin committed Jan 9, 2016
1 parent 94a8f9a commit 8fe96db
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 45 deletions.
28 changes: 28 additions & 0 deletions lib/dot/defaults.def
Original file line number Diff line number Diff line change
@@ -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 }}
{{?}}
{{~}}
#}}
10 changes: 1 addition & 9 deletions lib/dot/items.jst
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 3 additions & 11 deletions lib/dot/properties.jst
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
22 changes: 1 addition & 21 deletions lib/dot/required.jst
Original file line number Diff line number Diff line change
Expand Up @@ -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 + ']'
Expand All @@ -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 }}
Expand Down Expand Up @@ -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;
}

Expand All @@ -95,7 +76,6 @@
{{?}}

for (var {{=$i}} = 0; {{=$i}} < schema{{=$lvl}}.length; {{=$i}}++) {
{{# def.checkDefaults }}
if ({{=$data}}[schema{{=$lvl}}[{{=$i}}]] === undefined) {
{{# def.addError:'required' }}
}
Expand Down
8 changes: 8 additions & 0 deletions lib/dot/validate.jst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.defaults }}

{{ /**
* schema compilation (render) time:
Expand Down Expand Up @@ -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 }}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ajv",
"version": "3.1.1",
"version": "3.2.0",
"description": "Another JSON Schema Validator",
"main": "lib/ajv.js",
"files": [
Expand Down
7 changes: 5 additions & 2 deletions scripts/compile-dots.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
4 changes: 3 additions & 1 deletion spec/options.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -380,6 +381,7 @@ describe('Ajv Options', function () {
{ type: 'number', default: 1 },
{ type: 'boolean', default: false }
],
minItems: 3
};

var validate = ajv.compile(schema);
Expand Down

0 comments on commit 8fe96db

Please sign in to comment.