inline simple rules

master
Evgeny Poberezkin 2015-05-30 09:53:04 +01:00
parent 5de2ee7513
commit 884fcfb511
28 changed files with 416 additions and 351 deletions

2
.gitignore vendored
View File

@ -25,3 +25,5 @@ build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
.DS_Store

View File

@ -84,9 +84,8 @@ function Ajv(opts) {
function _addSchema(schema) {
if (typeof schema == 'string') schema = JSON.parse(schema);
if (typeof schema != 'object') throw new Error('schema has invalid type');
// var str = stableStringify(schema);
// return (self._byJson[str] = self._byJson[str] || compileSchema.call(self, schema));
return compileSchema.call(self, schema);
var str = stableStringify(schema);
return (self._byJson[str] = self._byJson[str] || compileSchema.call(self, schema));
}
}

View File

@ -7,6 +7,19 @@
* RULES, copy are defined in the parent scope in index.js
*/ }}
{{
function compareRules(key1, key2) {
var rule1 = it.RULES[key1]
, rule2 = it.RULES[key2]
, order1 = rule1 && rule1.order || 0
, order2 = rule2 && rule2.order || 0;
if (order1 < order2) return -1;
if (order1 > order2) return +1;
if (order1 == order2) return 0;
}
}}
function (data, dataType, dataPath) {
'use strict';
@ -14,8 +27,10 @@ function (data, dataType, dataPath) {
var errors = [];
{{?}}
{{ var $schemaKeys = Object.keys(it.schema); }}
{{ /* sort keys so that those that are easier to fail (e.g. type) are validated sooner */ }}
{{
var $schemaKeys = Object.keys(it.schema);
$schemaKeys.sort(compareRules);
}}
{{
var $checkProperties = !it.schema.properties &&
@ -31,14 +46,18 @@ function (data, dataType, dataPath) {
/* check if rule applies to data type */
if ( !rule.type || rule.type == dataType ) {
{{
var $it = it.copy(it);
$it.schema = it.schema[$key];
$it.schemaPath = it.schemaPath + '.' + $key;
$it.parentSchema = it.schema;
$it.parentSchemaPath = it.schemaPath;
}}
var result = ({{= $rule.code($it) }})(data, dataType, dataPath);
{{? $rule.inline}}
{{= $rule.code(it) }}
{{??}}
{{
var $it = it.copy(it);
$it.schema = it.schema[$key];
$it.schemaPath = it.schemaPath + '.' + $key;
$it.parentSchema = it.schema;
$it.parentSchemaPath = it.schemaPath;
}}
var result = ({{= $rule.code($it) }})(data, dataType, dataPath);
{{?}}
if (!result.valid) {
{{? it.opts.allErrors }}

View File

@ -23,7 +23,7 @@ function (data, dataType, dataPath) {
keyword: 'dependencies',
schema: self.schema{{= it.schemaPath }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, {{? $deps.length == 1 }}property {{= $deps[0] }} is{{??}}properties {{= $deps.join(",") }} are{{?}} required when property {{= $property }} is present'
message: '{{? $deps.length == 1 }}property {{= $deps[0] }} is{{??}}properties {{= $deps.join(",") }} are{{?}} required when property {{= $property }} is present'
{{? it.opts.verbose }}, data: data{{?}}
};

View File

@ -19,7 +19,7 @@ function (data, dataType, dataPath) {
keyword: 'enum',
schema: self.schema{{= it.schemaPath }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should be equal to one of values in the schema'
message: 'should be equal to one of values'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,23 +1,19 @@
function (data, dataType, dataPath) {
'use strict';
{{? it.opts.format !== false }}
var format = formats['{{= it.schema.format }}'];
var valid = typeof format == 'function'
? format(data)
: !format || format.test(data);
{{? it.opts.format !== false }}
var format = formats['{{= it.schema }}'];
var valid = typeof format == 'function'
? format(data)
: !format || format.test(data);
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'format',
schema: '{{= it.schema }}',
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should match format "{{= it.schema }}"'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
{{??}}
return { valid: true, errors: [] };
{{?}}
}
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'format',
schema: '{{= it.schema.format }}',
dataPath: dataPath,
message: 'should match format "{{= it.schema.format }}"'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
{{??}}
return { valid: true, errors: [] };
{{?}}

View File

@ -4,75 +4,103 @@ var fs = require('fs')
, doT = require('dot');
var RULES = module.exports = {
type: { code: fs.readFileSync(__dirname + '/type.dot.js') },
enum: { code: fs.readFileSync(__dirname + '/enum.dot.js') },
allOf: { code: fs.readFileSync(__dirname + '/allOf.dot.js') },
anyOf: { code: fs.readFileSync(__dirname + '/anyOf.dot.js') },
oneOf: { code: fs.readFileSync(__dirname + '/oneOf.dot.js') },
not: { code: fs.readFileSync(__dirname + '/not.dot.js') },
type: { code: fs.readFileSync(__dirname + '/type.dot.js'), inline: true, order: 10 },
enum: { code: fs.readFileSync(__dirname + '/enum.dot.js'), order: 80 },
allOf: { code: fs.readFileSync(__dirname + '/allOf.dot.js'), order: 110 },
anyOf: { code: fs.readFileSync(__dirname + '/anyOf.dot.js'), order: 100 },
oneOf: { code: fs.readFileSync(__dirname + '/oneOf.dot.js'), order: 110 },
not: { code: fs.readFileSync(__dirname + '/not.dot.js'), order: 90 },
maximum: { // includes exclusiveMaximum
code: fs.readFileSync(__dirname + '/maximum.dot.js'),
type: 'number'
type: 'number',
inline: true,
order: 20
},
minimum: { // includes exclusiveMinimum
code: fs.readFileSync(__dirname + '/minimum.dot.js'),
type: 'number'
type: 'number',
inline: true,
order: 20
},
multipleOf: {
code: fs.readFileSync(__dirname + '/multipleOf.dot.js'),
type: 'number'
type: 'number',
inline: true,
order: 40
},
maxLength: {
code: fs.readFileSync(__dirname + '/maxLength.dot.js'),
type: 'string'
type: 'string',
inline: true,
order: 50
},
minLength: {
code: fs.readFileSync(__dirname + '/minLength.dot.js'),
type: 'string'
type: 'string',
inline: true,
order: 50
},
pattern: {
code: fs.readFileSync(__dirname + '/pattern.dot.js'),
type: 'string'
type: 'string',
inline: true,
order: 60
},
format: {
code: fs.readFileSync(__dirname + '/format.dot.js'),
type: 'string'
type: 'string',
inline: true,
order: 70
},
items: { // includes additionalItems
code: fs.readFileSync(__dirname + '/items.dot.js'),
type: 'array'
type: 'array',
order: 120
},
maxItems: {
code: fs.readFileSync(__dirname + '/maxItems.dot.js'),
type: 'array'
type: 'array',
inline: true,
order: 20
},
minItems: {
code: fs.readFileSync(__dirname + '/minItems.dot.js'),
type: 'array'
type: 'array',
inline: true,
order: 20
},
uniqueItems: {
code: fs.readFileSync(__dirname + '/uniqueItems.dot.js'),
type: 'array'
type: 'array',
order: 110
},
maxProperties: {
code: fs.readFileSync(__dirname + '/maxProperties.dot.js'),
type: 'object'
type: 'object',
inline: true,
order: 30
},
minProperties: {
code: fs.readFileSync(__dirname + '/minProperties.dot.js'),
type: 'object'
type: 'object',
inline: true,
order: 30
},
required: {
code: fs.readFileSync(__dirname + '/required.dot.js'),
type: 'object'
type: 'object',
inline: true,
order: 80
},
properties: { // includes patternProperties and additionalProperties
code: fs.readFileSync(__dirname + '/properties.dot.js'),
type: 'object'
type: 'object',
order: 130
},
dependencies: {
code: fs.readFileSync(__dirname + '/dependencies.dot.js'),
type: 'object'
type: 'object',
order: 140
}
};

View File

@ -28,7 +28,7 @@ function (data, dataType, dataPath) {
keyword: 'additionalItems',
schema: false,
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should NOT have more than {{= it.schema.length }} items'
message: 'should NOT have more than {{= it.schema.length }} items'
{{? it.opts.verbose }}, data: data{{?}}
});

View File

@ -1,16 +1,12 @@
function (data, dataType, dataPath) {
'use strict';
var valid = data.length <= {{= it.schema.maxItems }};
var valid = data.length <= {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'maxItems',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should NOT have more than {{= it.schema }} items'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'maxItems',
schema: {{= it.schema.maxItems }},
dataPath: dataPath,
message: 'should NOT have more than {{= it.schema.maxItems }} items'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,16 +1,12 @@
function (data, dataType, dataPath) {
'use strict';
var valid = data.length <= {{= it.schema.maxLength }};
var valid = data.length <= {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'maxLength',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should NOT be longer than {{= it.schema }} characters'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'maxLength',
schema: {{= it.schema.maxLength }},
dataPath: dataPath,
message: 'should NOT be longer than {{= it.schema.maxLength }} characters'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,17 +1,13 @@
function (data, dataType, dataPath) {
'use strict';
var propertiesNum = Object.keys(data).length;
var valid = propertiesNum <= {{= it.schema.maxProperties }};
var propertiesNum = Object.keys(data).length;
var valid = propertiesNum <= {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'maxProperties',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should NOT have more than {{= it.schema }} properties'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'maxProperties',
schema: {{= it.schema.maxProperties }},
dataPath: dataPath,
message: 'should NOT have more than {{= it.schema.maxProperties }} properties'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,17 +1,17 @@
function (data, dataType, dataPath) {
'use strict';
{{
var $schema = it.schema.maximum
, $exclusive = it.schema.exclusiveMaximum === true
, $op = $exclusive ? '<' : '<=';
}}
{{ var $exclusive = it.parentSchema.exclusiveMaximum === true; }}
{{ var $op = $exclusive ? '<' : '<='; }}
var valid = data {{= $op }} {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'maximum',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should be {{= $op }} {{= it.schema }}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var valid = data {{= $op }} {{= $schema }};
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'maximum',
schema: {{= $schema }},
dataPath: dataPath,
message: 'should be {{= $op }} {{= $schema }}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,16 +1,12 @@
function (data, dataType, dataPath) {
'use strict';
var valid = data.length >= {{= it.schema.minItems }};
var valid = data.length >= {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'minItems',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should NOT have less than {{= it.schema }} items'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'minItems',
schema: {{= it.schema.minItems }},
dataPath: dataPath,
message: 'should NOT have less than {{= it.schema.minItems }} items'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,16 +1,12 @@
function (data, dataType, dataPath) {
'use strict';
var valid = data.length >= {{= it.schema.minLength }};
var valid = data.length >= {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'minLength',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should NOT be shorter than {{= it.schema }} characters'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'minLength',
schema: {{= it.schema.minLength }},
dataPath: dataPath,
message: 'should NOT be shorter than {{= it.schema.minLength }} characters'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,17 +1,13 @@
function (data, dataType, dataPath) {
'use strict';
var propertiesNum = Object.keys(data).length;
var valid = propertiesNum >= {{= it.schema.minProperties }};
var propertiesNum = Object.keys(data).length;
var valid = propertiesNum >= {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'minProperties',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should NOT have less than {{= it.schema }} properties'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'minProperties',
schema: {{= it.schema.minProperties }},
dataPath: dataPath,
message: 'should NOT have less than {{= it.schema.minProperties }} properties'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,17 +1,17 @@
function (data, dataType, dataPath) {
'use strict';
{{
var $schema = it.schema.minimum
, $exclusive = it.schema.exclusiveMinimum === true
, $op = $exclusive ? '>' : '>=';
}}
{{ var $exclusive = it.parentSchema.exclusiveMinimum === true; }}
{{ var $op = $exclusive ? '>' : '>='; }}
var valid = data {{= $op }} {{= it.schema }};
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'minimum',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should be {{= $op }} {{= it.schema }}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var valid = data {{= $op }} {{= $schema }};
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'minimum',
schema: {{= $schema }},
dataPath: dataPath,
message: 'should be {{= $op }} {{= $schema }}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -1,17 +1,13 @@
function (data, dataType, dataPath) {
'use strict';
var division = data / {{= it.schema.multipleOf }};
var valid = division === parseInt(division);
var division = data / {{= it.schema }};
var valid = division === parseInt(division);
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'multipleOf',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should be multiple of {{= it.schema }}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'multipleOf',
schema: {{= it.schema.multipleOf }},
dataPath: dataPath,
message: 'should be multiple of {{= it.schema.multipleOf }}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -7,7 +7,7 @@ function (data, dataType, dataPath) {
keyword: 'not',
schema: self.schema{{= it.schemaPath }},
dataPath: dataPath,
message: 'data' + dataPath + ' is valid according to schema, should be NOT valid'
message: 'should NOT be valid'
{{? it.opts.verbose }}, data: data{{?}}
}];
return result;

View File

@ -17,7 +17,7 @@ function (data, dataType, dataPath) {
keyword: 'oneOf',
schema: self.schema{{= it.schemaPath }},
dataPath: dataPath,
message: 'data' + dataPath + ' NOT valid, matches more that one schema in oneOf'
message: 'should match exactly one schema in oneOf'
{{? it.opts.verbose }}, data: data{{?}}
}] };
foundValid = true;
@ -30,7 +30,7 @@ function (data, dataType, dataPath) {
keyword: 'oneOf',
schema: self.schema{{= it.schemaPath }},
dataPath: dataPath,
message: 'data' + dataPath + ' NOT valid, matches none of the schemas in oneOf'
message: 'should match exactly one schema in oneOf'
{{? it.opts.verbose }}, data: data{{?}}
});

View File

@ -1,17 +1,13 @@
function (data, dataType, dataPath) {
'use strict';
{{ new RegExp(it.schema.pattern); /* test if regexp is valid to fail at compile time rather than in eval */}}
var valid = /{{= it.schema.pattern }}/.test(data);
{{ new RegExp(it.schema); /* test if regexp is valid to fail at compile time rather than in eval */}}
var valid = /{{= it.schema }}/.test(data);
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'minimum',
schema: '{{= it.schema }}',
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, should match pattern "{{= it.schema }}"'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'minimum',
schema: '{{= it.schema.pattern }}',
dataPath: dataPath,
message: 'should match pattern "{{= it.schema.pattern }}"'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -47,7 +47,7 @@ function (data, dataType, dataPath) {
keyword: 'properties',
schema: propertiesSchema,
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, additional properties NOT allowed'
message: 'additional properties NOT allowed'
{{? it.opts.verbose }}, data: data{{?}}
};
@ -94,7 +94,7 @@ function (data, dataType, dataPath) {
keyword: 'properties',
schema: propertiesSchema,
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, property ' + key + ' NOT allowed'
message: 'property ' + key + ' NOT allowed'
{{? it.opts.verbose }}, data: data{{?}}
};

View File

@ -1,36 +1,32 @@
function (data, dataType, dataPath) {
'use strict';
var valid = true, missing = '';
var schema = self.schema{{= it.schemaPath + '.required' }};
var valid = true, missing = '';
var schema = self.schema{{= it.schemaPath }};
for (var i = 0; i < schema.length; i++) {
var property = schema[i]
, has = data.hasOwnProperty(schema[i])
, valid = valid && has;
for (var i = 0; i < schema.length; i++) {
var property = schema[i]
, has = data.hasOwnProperty(schema[i])
, valid = valid && has;
if (!has) {
{{? it.opts.allErrors }}
missing += ', ' + property;
{{??}}
missing = property;
break;
{{?}}
}
if (!has) {
{{? it.opts.allErrors }}
missing += ', ' + property;
{{??}}
missing = property;
break;
{{?}}
}
{{? it.opts.allErrors }}
missing = missing.slice(2);
{{?}}
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'required',
schema: self.schema{{= it.schemaPath }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, properties ' + missing + ' are missing'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
{{? it.opts.allErrors }}
missing = missing.slice(2);
{{?}}
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'required',
schema: self.schema{{= it.schemaPath + '.required' }},
dataPath: dataPath,
message: 'properties ' + missing + ' are missing'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -0,0 +1,58 @@
{{## def.isInteger:
dataType == 'number' &&
(data === parseInt(data) ||
data > 9007199254740992 ||
data < -9007199254740992)
#}}
function (data, dataType, dataPath) {
'use strict';
{{
var $schema = it.schema;
var $isArray = Array.isArray($schema);
if ($isArray && $schema.length == 1) {
$schema = $schema[0];
$isArray = false;
}
}}
var valid;
{{? $isArray }}
{{? $schema.indexOf('integer') >= 0 }}
valid = {{~ $schema:$t }}
{{? $t != 'integer' }}
{{? $notFirst }} || {{?}}
{{ var $notFirst = true; }}
dataType == '{{=$t}}'
{{?}}
{{~}};
if (!valid) {
valid = {{# def.isInteger }};
}
{{??}}
valid = {{~ $schema:$t:$i }}
{{? $i }} || {{?}}
dataType == '{{=$t}}'
{{~}};
{{?}}
{{??}}
valid = {{? $schema == 'integer' }}
{{# def.isInteger }};
{{??}}
dataType == '{{= $schema }}';
{{?}};
{{?}}
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'type',
schema: {{? $isArray }}self.schema{{= it.schemaPath }}{{??}}'{{= $schema }}'{{?}},
dataPath: dataPath,
message: 'should be {{? $isArray }}one of {{= $schema.join(",") }}{{??}}{{= $schema }}{{?}}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}

View File

@ -6,53 +6,49 @@
#}}
function (data, dataType, dataPath) {
'use strict';
{{
var $schema = it.schema.type;
var $isArray = Array.isArray($schema);
if ($isArray && $schema.length == 1) {
$schema = $schema[0];
$isArray = false;
}
}}
{{
var $schema = it.schema;
var $isArray = Array.isArray($schema);
if ($isArray && $schema.length == 1) {
$schema = $schema[0];
$isArray = false;
}
}}
var valid;
{{? $isArray }}
{{? $schema.indexOf('integer') >= 0 }}
valid = {{~ $schema:$t }}
{{? $t != 'integer' }}
{{? $notFirst }} || {{?}}
{{ var $notFirst = true; }}
dataType == '{{=$t}}'
{{?}}
{{~}};
if (!valid) {
valid = {{# def.isInteger }};
}
{{??}}
valid = {{~ $schema:$t:$i }}
{{? $i }} || {{?}}
var valid;
{{? $isArray }}
{{? $schema.indexOf('integer') >= 0 }}
valid = {{~ $schema:$t }}
{{? $t != 'integer' }}
{{? $notFirst }} || {{?}}
{{ var $notFirst = true; }}
dataType == '{{=$t}}'
{{~}};
{{?}}
{{?}}
{{~}};
if (!valid) {
valid = {{# def.isInteger }};
}
{{??}}
valid = {{? $schema == 'integer' }}
{{# def.isInteger }};
{{??}}
dataType == '{{= $schema }}';
{{?}};
valid = {{~ $schema:$t:$i }}
{{? $i }} || {{?}}
dataType == '{{=$t}}'
{{~}};
{{?}}
{{??}}
valid = {{? $schema == 'integer' }}
{{# def.isInteger }};
{{??}}
dataType == '{{= $schema }}';
{{?}};
{{?}}
return {
valid: valid,
errors: valid ? [] : [{
keyword: 'type',
schema: {{? $isArray }}self.schema{{= it.schemaPath }}{{??}}'{{= $schema }}'{{?}},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid. Expected {{? $isArray }}{{= $schema.join(",") }}{{??}}{{= $schema }}{{?}}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};
}
var result = {
valid: valid,
errors: valid ? [] : [{
keyword: 'type',
schema: {{? $isArray }}self.schema{{= it.schemaPath + '.type' }}{{??}}'{{= $schema }}'{{?}},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid. Expected {{? $isArray }}{{= $schema.join(",") }}{{??}}{{= $schema }}{{?}}'
{{? it.opts.verbose }}, data: data{{?}}
}]
};

View File

@ -13,7 +13,7 @@ function (data, dataType, dataPath) {
keyword: 'uniqueItems',
schema: {{= it.schema }},
dataPath: dataPath,
message: 'data' + dataPath + ' is not valid, item #' + i + 'is duplicate'
message: 'item #' + i + 'is duplicate'
{{? it.opts.verbose }}, data: data{{?}}
};

View File

@ -1,6 +1,6 @@
{
"name": "ajv",
"version": "0.0.7",
"version": "0.0.8",
"description": "Another JSON schema Validator",
"main": "lib/ajv.js",
"scripts": {

View File

@ -33,14 +33,14 @@ describe.only('JSON-Schema tests', function () {
var testSets = require(file.path);
testSets.forEach(function (testSet) {
// if (testSet.description != 'validation of URIs') return;
// describe(testSet.description, function() {
it(testSet.description, function() {
describe(testSet.description, function() {
// it(testSet.description, function() {
var validate = ajv.compile(testSet.schema);
var fullValidate = fullAjv.compile(testSet.schema);
testSet.tests.forEach(function (test) {
// if (test.description != 'a valid date-time string') return;
// it(test.description, function() {
it(test.description, function() {
var result = validate(test.data);
// console.log('result', result);
assert.equal(result.valid, test.valid);
@ -52,7 +52,7 @@ describe.only('JSON-Schema tests', function () {
assert.equal(result.valid, test.valid);
if (result.valid) assert(result.errors.length == 0);
else assert(result.errors.length > 0);
// });
});
});
});
});

97
try.js
View File

@ -1,53 +1,47 @@
var out = 'function (data, dataType, dataPath) { \'use strict\'; var errors = []; ';
var $schemaDeps = {},
$propertyDeps = {};
for ($property in it.schema) {
var $schema = it.schema[$property];
var $deps = Array.isArray($schema) ? $propertyDeps : $schemaDeps;
$deps[$property] = $schema;
var out = '';
out += 'function (data, dataType, dataPath) { \'use strict\'; ';
if (it.opts.allErrors) {
out += ' var errors = []; ';
}
out += ' ';
for ($property in $propertyDeps) {
out += ' if (data.hasOwnProperty(\'' + ($property) + '\')) { ';
$deps = $propertyDeps[$property] out += ' var valid = ';
var arr1 = $deps;
if (arr1) {
var $dep, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$dep = arr1[$i += 1];
if ($i) {
out += ' || ';
var $schemaKeys = Object.keys(it.schema);
$schemaKeys.sort(compareRules);
out += ' ';
var $checkProperties = !it.schema.properties && (it.schema.patternProperties || it.schema.hasOwnProperty('additionalProperties'));
if ($checkProperties) $schemaKeys.push('properties');
out += ' ';
var arr1 = $schemaKeys;
if (arr1) {
var $key, i1 = -1,
l1 = arr1.length - 1;
while (i1 < l1) {
$key = arr1[i1 += 1];
out += ' ';
var $rule = it.RULES[$key];
out += ' ';
if ($rule) {
out += ' var rule = RULES.' + ($key) + '; if ( !rule.type || rule.type == dataType ) { ';
if ($rule.inline) {
out += ' ' + ($rule.code(it)) + ' ';
} else {
out += ' ';
var $it = it.copy(it);
$it.schema = it.schema[$key];
$it.schemaPath = it.schemaPath + '.' + $key;
$it.parentSchema = it.schema;
$it.parentSchemaPath = it.schemaPath;
out += ' var result = (' + ($rule.code($it)) + ')(data, dataType, dataPath); ';
}
out += 'data.hasOwnProperty(\'' + ($dep) + '\')';
out += ' if (!result.valid) { ';
if (it.opts.allErrors) {
out += ' errors.push.apply(errors, result.errors); ';
} else {
out += ' return result; ';
}
out += ' } } ';
}
out += ' ';
}
out += '; if (!valid) { var error = { keyword: \'dependencies\', schema: self.schema' + (it.schemaPath) + ', dataPath: dataPath, message: \'data\' + dataPath + \' is not valid, properties ' + ($deps.join(",")) + ' are required when property ' + ($property) + ' is present\' ';
if (it.opts.verbose) {
out += ', data: data';
}
out += ' } ';
if (it.opts.allErrors) {
out += ' errors.push(error); ';
} else {
out += ' return { valid: false, errors: [error] }; ';
}
out += ' } } ';
}
out += ' ';
for ($property in $schemaDeps) {
out += ' if (data.hasOwnProperty(\'' + ($property) + '\')) { ';
var $schema = $schemaDeps[$property];
var $it = it.copy(it);
$it.schema = $schema;
$it.schemaPath = it.schemaPath + '["' + it.escapeQuotes($property) + '"]';
out += ' var result = (' + (it._validate($it)) + ')(data, dataType, dataPath); if (!result.valid) { ';
if (it.opts.allErrors) {
out += ' errors.push.apply(errors, result.errors); ';
} else {
out += ' return { valid: false, errors: result.errors }; ';
}
out += ' } } ';
}
out += ' ';
if (it.opts.allErrors) {
@ -55,5 +49,14 @@ if (it.opts.allErrors) {
} else {
out += ' return { valid: true, errors: [] }; ';
}
out += '}';
return out;
out += ' ';
function compareRules(key1, key2) {
var order1 = it.RULES[key1].order,
order2 = it.RULES[key2].order;
if (order1 < order2) return -1;
if (order1 > order2) return +1;
if (order1 == order2) return 0;
}
}
return out