Merge branch 'master' into inline

master
Evgeny Poberezkin 2015-08-23 12:04:38 +01:00
commit f3b65f4a58
44 changed files with 176 additions and 1201 deletions

3
.gitignore vendored
View File

@ -28,6 +28,9 @@ node_modules
.DS_Store
# Compiled templates
lib/dotjs/*.js
# Browserified tests
.browser

View File

@ -135,7 +135,7 @@ All the instance methods below are bound to the instance, so they can be used wi
Generate validating function and cache the compiled schema for future use.
Validating function returns boolean and has properties `errors` with the errors from the last validation (`null` if there were no errors) and `schema` with the reference to the original schema.
Validating function returns boolean and has properties `errors` with the errors from the last validation (`null` if there were no errors) and `schema` with the reference to the original schema.
Unless the option `validateSchema` is false, the schema will be validated against meta-schema and if schema is invalid the error will be thrown. See [options](#options).
@ -169,7 +169,7 @@ By default the schema is validated against meta-schema before it is added, and i
Adds meta schema that can be used to validate other schemas. That function should be used instead of `addSchema` because there may be instance options that would compile a meta schema incorrectly (at the moment it is `removeAdditional` option).
There is no need to explicitely add draft 4 meta schema (http://json-schema.org/draft-04/schema) - it is added by default, unless option `meta` is set to `false`. You only need to use it if you have a changed meta-schema that you want to use to validate your schemas. See `validateSchema`.
There is no need to explicitly add draft 4 meta schema (http://json-schema.org/draft-04/schema and http://json-schema.org/schema) - it is added by default, unless option `meta` is set to `false`. You only need to use it if you have a changed meta-schema that you want to use to validate your schemas. See `validateSchema`.
##### .validateSchema(Object schema) -> Boolean
@ -224,13 +224,13 @@ Options can have properties `separator` (string used to separate errors, ", " by
- _formats_: an object with custom formats. Keys and values will be passed to `addFormat` method.
- _schemas_: an array or object of schemas that will be added to the instance. If the order is important, pass array. In this case schemas must have IDs in them. Otherwise the object can be passed - `addSchema(value, key)` will be called for each schema in this object.
- _meta_: add [meta-schema](http://json-schema.org/documentation.html) so it can be used by other schemas (true by default).
- _validateSchema_: validate added/compiled schemas against meta-schema (true by default). `$schema` property in the schema can either be http://json-schema.org/draft-04/schema or absent (draft-4 meta-schema will be used) or can be a reference to the schema previously added with `addMetaSchema` method. If the validation fails, the exception is thrown. Pass "log" in this option to log error instead of throwing exception. Pass `false` to skip schema validation.
- _validateSchema_: validate added/compiled schemas against meta-schema (true by default). `$schema` property in the schema can either be http://json-schema.org/schema or http://json-schema.org/draft-04/schema or absent (draft-4 meta-schema will be used) or can be a reference to the schema previously added with `addMetaSchema` method. If the validation fails, the exception is thrown. Pass "log" in this option to log error instead of throwing exception. Pass `false` to skip schema validation.
- _missingRefs_: by default if the reference cannot be resolved during compilation the exception is thrown. Pass 'ignore' to log error during compilation and pass validation. Pass 'fail' to log error and successfully compile schema but fail validation if this rule is checked.
- _uniqueItems_: validate `uniqueItems` keyword (true by default).
- _unicode_: calculate correct length of strings with unicode pairs (true by default). Pass `false` to use `.length` of strings that is faster, but gives "incorrect" lengths of strings with unicode pairs - each unicode pair is counted as two characters.
- _beautify_: format the generated function with [js-beautify](https://github.com/beautify-web/js-beautify) (the validating function is generated without line-breaks). `npm install js-beautify` to use this option. `true` or js-beautify options can be passed.
- _cache_: an optional instance of cache to store compiled schemas using stable-stringified schema as a key. For example, set-associative cache [sacjs](https://github.com/epoberezkin/sacjs) can be used. If not passed then a simple hash is used which is good enough for the common use case (a limited number of statically defined schemas). Cache should have methods `put(key, value)`, `get(key)` and `del(key)`.
- _cache_: an optional instance of cache to store compiled schemas using stable-stringified schema as a key. For example, set-associative cache [sacjs](https://github.com/epoberezkin/sacjs) can be used. If not passed then a simple hash is used which is good enough for the common use case (a limited number of statically defined schemas). Cache should have methods `put(key, value)`, `get(key)` and `del(key)`.
- _jsonPointers_: Output `dataPath` using JSON Pointers instead of JS path notation.
## Tests
@ -240,23 +240,13 @@ git submodule update --init
npm test
```
Browser:
```
bin/prepare-tests
karma start
```
## Contributing
All validation functions are generated using doT templates in [dot](https://github.com/epoberezkin/ajv/tree/master/lib/dot) folder. Templates are precompiled so doT is not a run-time dependency.
`bin/compile-dots` - compiles templates to [dotjs](https://github.com/epoberezkin/ajv/tree/master/lib/dotjs) folder (please use node 0.10 to compile - 0.12 is fully supported but it inserts some empty comments in function parameters when Function constructor is called).
`npm run build` - compiles templates to [dotjs](https://github.com/epoberezkin/ajv/tree/master/lib/dotjs) folder (please use node 0.10 to compile - 0.12 is fully supported but it inserts some empty comments in function parameters when Function constructor is called).
`bin/watch-dots` - automatically compiles templates when files in dot folder change
`bin/git-hook` - installs symbolic link to pre-commit hook that will compile templates and run tests.
`npm run watch` - automatically compiles templates when files in dot folder change
## Changes history

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
node ./bin/compile-dots.js

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
browserify -r ./lib/ajv.js:ajv -o ajv.bundle.js

View File

@ -1,7 +0,0 @@
#!/usr/bin/env bash
set -e
hook=.git/hooks/pre-commit
[ -e "$hook" ] || [ -h "$hook" ] && rm $hook
ln -s $(pwd)/bin/pre-commit $hook

View File

@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -e
bin/compile-dots
npm run test-spec

View File

@ -1,2 +0,0 @@
#!/usr/bin/env bash
./node_modules/.bin/watch 'node bin/compile-dots.js' ./lib/dot

View File

@ -259,8 +259,11 @@ function Ajv(opts) {
function addInitialSchemas() {
if (self.opts.meta !== false)
addMetaSchema(require('./refs/json-schema-draft-04.json'), META_SCHEMA_ID, true);
if (self.opts.meta !== false) {
var metaSchema = require('./refs/json-schema-draft-04.json');
addMetaSchema(metaSchema, META_SCHEMA_ID, true);
self._refs['http://json-schema.org/schema'] = META_SCHEMA_ID;
}
var optsSchemas = self.opts.schemas;
if (!optsSchemas) return;

View File

@ -16,7 +16,9 @@ function compile(schema, root, localRefs) {
/* jshint validthis: true, evil: true */
var self = this
, refVal = [ undefined ]
, refs = {};
, refs = {}
, patterns = []
, patternsHash = {};
root = root || { schema: schema, refVal: refVal, refs: refs };
@ -42,10 +44,13 @@ function compile(schema, root, localRefs) {
util: util,
resolve: resolve,
resolveRef: resolveRef,
usePattern: usePattern,
opts: self.opts,
formats: formats
});
validateCode = patternsCode(patterns) + validateCode;
if (self.opts.beautify) {
var opts = self.opts.beautify === true ? { indent_size: 2 } : self.opts.beautify;
if (beautify) validateCode = beautify(validateCode, opts);
@ -122,6 +127,23 @@ function compile(schema, root, localRefs) {
? { schema: schema, code: code }
: code;
}
function usePattern(regexStr) {
var index = patternsHash[regexStr];
if (index === undefined) {
index = patternsHash[regexStr] = patterns.length;
patterns[index] = regexStr;
}
return 'pattern' + index;
}
function patternsCode(patterns) {
if (!patterns.length) return '';
var code = '';
for (var i=0; i<patterns.length; i++)
code += 'var pattern' + i + ' = new RegExp(' + util.toQuotedString(patterns[i]) + ');'
return code;
}
}

View File

@ -8,14 +8,16 @@ module.exports = {
toHash: toHash,
getProperty: getProperty,
escapeQuotes: escapeQuotes,
escapeRegExp: escapeRegExp,
ucs2length: ucs2length,
varOccurences: varOccurences,
varReplace: varReplace,
cleanUpCode: cleanUpCode,
cleanUpVarErrors: cleanUpVarErrors,
schemaHasRules: schemaHasRules,
stableStringify: require('json-stable-stringify')
stableStringify: require('json-stable-stringify'),
toQuotedString: toQuotedString,
getPathExpr: getPathExpr,
getPath: getPath
};
@ -34,10 +36,10 @@ function checkDataType(dataType, data, negate) {
switch (dataType) {
case 'null': return data + EQUAL + 'null';
case 'array': return OK + 'Array.isArray(' + data + ')';
case 'object': return '(' + OK + data + AND +
'typeof ' + data + EQUAL + '"object"' + AND +
case 'object': return '(' + OK + data + AND +
'typeof ' + data + EQUAL + '"object"' + AND +
NOT + 'Array.isArray(' + data + '))';
case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND +
case 'integer': return '(typeof ' + data + EQUAL + '"number"' + AND +
NOT + '(' + data + ' % 1))';
default: return 'typeof ' + data + EQUAL + '"' + dataType + '"';
}
@ -79,22 +81,16 @@ function toHash(arr) {
var IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
var SINGLE_QUOTE = /('|\\)/g;
var SINGLE_QUOTE = /'|\\/g;
function getProperty(key) {
return IDENTIFIER.test(key)
? '.' + key
: "['" + key.replace(SINGLE_QUOTE, "\\$1") + "']";
: "['" + key.replace(SINGLE_QUOTE, '\\$&') + "']";
}
function escapeQuotes(str) {
return str.replace(SINGLE_QUOTE, "\\$1");
}
var ESCAPE_REGEXP = /[\/]/g;
function escapeRegExp(str) {
return str.replace(ESCAPE_REGEXP, '\\$&');
return str.replace(SINGLE_QUOTE, '\\$&');
}
@ -145,7 +141,7 @@ var ERRORS_REGEXP = /[^v\.]errors/g
, REMOVE_ERRORS = /var errors = 0;|var vErrors = null;|validate.errors = vErrors;/g
, RETURN_VALID = 'return errors === 0;'
, RETURN_TRUE = 'validate.errors = null; return true;';
function cleanUpVarErrors(out) {
var matches = out.match(ERRORS_REGEXP);
if (matches && matches.length === 2)
@ -159,3 +155,30 @@ function cleanUpVarErrors(out) {
function schemaHasRules(schema, rules) {
for (var key in schema) if (rules[key]) return true;
}
function toQuotedString (str) {
return '\'' + escapeQuotes(str) + '\'';
}
function getPathExpr (currentPath, expr, jsonPointers, isNumber) {
var path = jsonPointers
? '\'/\' + ' + expr + (isNumber ? '' : '.replace(/~/g, \'~0\').replace(/\\//g, \'~1\')')
: '\'[\\\'\' + ' + expr + ' + \'\\\']\'';
return joinPaths(currentPath, path);
}
function getPath (currentPath, prop, jsonPointers) {
var path = jsonPointers
? toQuotedString('/' + prop.replace(/~/g, '~0').replace(/\//g, '~1'))
: toQuotedString(getProperty(prop));
return joinPaths(currentPath, path);
}
function joinPaths (a, b) {
if (a == '""') return b;
return (a + ' + ' + b).replace(/' \+ '/g, '');
}

View File

@ -149,13 +149,13 @@
{{## def._errorSchemas = {
$ref: "'{{=it.util.escapeQuotes($schema)}}'",
$ref: "{{=it.util.toQuotedString($schema)}}",
additionalItems: "false",
additionalProperties: "false",
anyOf: "validate.schema{{=$schemaPath}}",
dependencies: "validate.schema{{=$schemaPath}}",
enum: "validate.schema{{=$schemaPath}}",
format: "'{{=it.util.escapeQuotes($schema)}}'",
format: "{{=it.util.toQuotedString($schema)}}",
maximum: "{{=$schema}}",
minimum: "{{=$schema}}",
maxItems: "{{=$schema}}",
@ -167,7 +167,7 @@
multipleOf: "{{=$schema}}",
not: "validate.schema{{=$schemaPath}}",
oneOf: "validate.schema{{=$schemaPath}}",
pattern: "'{{=it.util.escapeQuotes($schema)}}'",
pattern: "{{=it.util.toQuotedString($schema)}}",
required: "validate.schema{{=$schemaPath}}",
type: "{{? $isArray }}['{{= $typeSchema.join(\"','\") }}']{{??}}'{{=$typeSchema}}'{{?}}",
uniqueItems: "{{=$schema}}"

View File

@ -6,7 +6,7 @@
{{## def.validateItems:startFrom:
for (var i{{=$lvl}} = {{=startFrom}}; i{{=$lvl}} < {{=$data}}.length; i{{=$lvl}}++) {
{{
$it.errorPath = (it.errorPath + ' + "[" + i' + $lvl + ' + "]"').replace('" + "', '');
$it.errorPath = it.util.getPathExpr(it.errorPath, 'i' + $lvl, it.opts.jsonPointers, true);
var $passData = $data + '[i' + $lvl + ']';
}}
@ -39,12 +39,12 @@ var {{=$valid}};
{{~ $schema:$sch:$i }}
{{? {{# def.nonEmptySchema:$sch }} }}
valid{{=$it.level}} = true;
if ({{=$data}}.length > {{=$i}}) {
{{
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errorPath = (it.errorPath + ' + "[' + $i + ']"').replace('" + "', '');
$it.errorPath = it.util.getPathExpr(it.errorPath, $i, it.opts.jsonPointers, true);
var $passData = $data + '[' + $i + ']';
}}

View File

@ -2,6 +2,6 @@
{{# def.setup:'pattern' }}
{{ new RegExp($schema); /* test if regexp is valid to fail at compile time rather than in eval */}}
if (! /{{= it.util.escapeRegExp($schema) }}/.test({{=$data}}) ) {
if (! {{= it.usePattern($schema) }}.test({{=$data}}) ) {
{{# def.error:'pattern' }}
} {{? $breakOnError }} else { {{?}}

View File

@ -30,7 +30,7 @@ var valid{{=$it.level}} = true;
{{? $pPropertyKeys.length }}
if (isAdditional{{=$lvl}}) {
{{~ $pPropertyKeys:$pProperty:$i }}
if (/{{= it.util.escapeRegExp($pProperty) }}/.test(key{{=$lvl}}))
if ({{= it.usePattern($pProperty) }}.test(key{{=$lvl}}))
isAdditional{{=$lvl}} = false;
{{? $i < $pPropertyKeys.length-1 }}
else
@ -45,7 +45,7 @@ var valid{{=$it.level}} = true;
{{??}}
{{
var $currentErrorPath = it.errorPath;
it.errorPath = (it.errorPath + ' + "[\'" + key' + $lvl + ' + "\']"').replace('" + "', '');
it.errorPath = it.util.getPathExpr(it.errorPath, 'key' + $lvl, it.opts.jsonPointers);
}}
{{? $noAdditional }}
{{? $removeAdditional }}
@ -100,7 +100,7 @@ var valid{{=$it.level}} = true;
var $prop = it.util.getProperty($propertyKey)
, $passData = $data + $prop;
$it.schemaPath = $schemaPath + $prop;
$it.errorPath = (it.errorPath + ' + "' + $prop + '"').replace('" + "', '');
$it.errorPath = it.util.getPath(it.errorPath, $propertyKey, it.opts.jsonPointers);
}}
{{ var $code = it.validate($it); }}
@ -140,9 +140,9 @@ var valid{{=$it.level}} = true;
}}
for (var key{{=$lvl}} in {{=$data}}) {
if (/{{= it.util.escapeRegExp($pProperty) }}/.test(key{{=$lvl}})) {
if ({{= it.usePattern($pProperty) }}.test(key{{=$lvl}})) {
{{
$it.errorPath = (it.errorPath + ' + "[\'" + key' + $lvl + ' + "\']"').replace('" + "', '');
$it.errorPath = it.util.getPathExpr(it.errorPath, 'key' + $lvl, it.opts.jsonPointers);
var $passData = $data + '[key' + $lvl + ']';
}}

View File

@ -5,7 +5,7 @@
{{~ $schema:$property:$i }}
{{? $i}} || {{?}}
{{ var $prop = it.util.getProperty($property); }}
( {{=$data}}{{=$prop}} === undefined && (missing{{=$lvl}} = '{{= it.util.escapeQuotes($prop) }}') )
( {{=$data}}{{=$prop}} === undefined && (missing{{=$lvl}} = {{= it.util.toQuotedString(it.opts.jsonPointers ? $property : $prop) }}) )
{{~}}
#}}
@ -13,9 +13,9 @@
var schema{{=$lvl}} = validate.schema{{=$schemaPath}};
{{
var $i = 'i' + $lvl
, $propertyPath = ' + schema' + $lvl + '[' + $i + '] + '
, $missingProperty = '\' + "\'"' + $propertyPath + '"\'" + \'';
it.errorPath = ($currentErrorPath + ' + "[\'"' + $propertyPath + '"\']"').replace('" + "', '');
, $propertyPath = 'schema' + $lvl + '[' + $i + ']'
, $missingProperty = '\' + "\'" + ' + $propertyPath + ' + "\'" + \'';
it.errorPath = it.util.getPathExpr($currentErrorPath, $propertyPath, it.opts.jsonPointers);
}}
#}}
@ -27,9 +27,11 @@
{{? $schema.length <= 20 }}
if ({{# def.checkRequired }}) {
{{
var $propertyPath = ' + missing' + $lvl
, $missingProperty = '\'' + $propertyPath + ' + \'';
it.errorPath = $currentErrorPath + $propertyPath;
var $propertyPath = 'missing' + $lvl
, $missingProperty = '\' + ' + $propertyPath + ' + \'';
it.errorPath = it.opts.jsonPointers
? it.util.getPathExpr($currentErrorPath, $propertyPath, true)
: $currentErrorPath + ' + ' + $propertyPath;
}}
{{# def.error:'required' }}
} else {
@ -50,7 +52,7 @@
{{
var $prop = it.util.getProperty($property)
, $missingProperty = it.util.escapeQuotes($prop);
it.errorPath = ($currentErrorPath + ' + \'' + $missingProperty + '\'').replace('" + "', '');
it.errorPath = it.util.getPath($currentErrorPath, $property, it.opts.jsonPointers);
}}
if ({{=$data}}{{=$prop}} === undefined) {
{{# def.addError:'required' }}

View File

@ -1,3 +1,3 @@
These files are compiled dot templates from dot folder.
Do NOT edit them directly, edit the templates and run `node bin/compile_dots` from main ajv folder.
Do NOT edit them directly, edit the templates and run `npm run build` from main ajv folder.

View File

@ -1,37 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['allOf'],
$schemaPath = it.schemaPath + '.' + 'allOf',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $it = it.util.copy(it),
$closingBraces = '';
$it.level++;
var arr1 = $schema;
if (arr1) {
var $sch, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$sch = arr1[$i += 1];
if (it.util.schemaHasRules($sch, it.RULES.all)) {
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
out += ' ' + (it.validate($it)) + ' ';
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
}
}
if ($breakOnError) {
out += ' ' + ($closingBraces.slice(0, -1));
}
out = it.util.cleanUpCode(out);
return out;
}

View File

@ -1,47 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['anyOf'],
$schemaPath = it.schemaPath + '.' + 'anyOf',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $it = it.util.copy(it),
$closingBraces = '';
$it.level++;
var $noEmptySchema = $schema.every(function($sch) {
return it.util.schemaHasRules($sch, it.RULES.all);
});
if ($noEmptySchema) {
out += ' var ' + ($errs) + ' = errors; var ' + ($valid) + ' = false; ';
var arr1 = $schema;
if (arr1) {
var $sch, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$sch = arr1[$i += 1];
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
out += ' ' + (it.validate($it)) + ' ' + ($valid) + ' = ' + ($valid) + ' || valid' + ($it.level) + '; if (!' + ($valid) + ') { ';
$closingBraces += '}';
}
}
out += ' ' + ($closingBraces) + ' if (!' + ($valid) + ') { var err = { keyword: \'' + ('anyOf') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should match some schema in anyOf\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } ';
if (it.opts.allErrors) {
out += ' } ';
}
out = it.util.cleanUpCode(out);
} else {
if ($breakOnError) {
out += ' if (true) { ';
}
}
return out;
}

View File

@ -1,90 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['dependencies'],
$schemaPath = it.schemaPath + '.' + 'dependencies',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $it = it.util.copy(it),
$closingBraces = '';
$it.level++;
var $schemaDeps = {},
$propertyDeps = {};
for ($property in $schema) {
var $sch = $schema[$property];
var $deps = Array.isArray($sch) ? $propertyDeps : $schemaDeps;
$deps[$property] = $sch;
}
out += 'var ' + ($errs) + ' = errors;';
for (var $property in $propertyDeps) {
out += ' if (' + ($data) + (it.util.getProperty($property)) + ' !== undefined) { ';
$deps = $propertyDeps[$property];
out += ' if ( ';
var arr1 = $deps;
if (arr1) {
var $dep, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$dep = arr1[$i += 1];
if ($i) {
out += ' || ';
}
out += ' ' + ($data) + (it.util.getProperty($dep)) + ' === undefined ';
}
}
out += ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('dependencies') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'';
if ($deps.length == 1) {
out += 'property ' + (it.util.escapeQuotes($deps[0])) + ' is';
} else {
out += 'properties ' + (it.util.escapeQuotes($deps.join(", "))) + ' are';
}
out += ' required when property ' + (it.util.escapeQuotes($property)) + ' is present\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('dependencies') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'';
if ($deps.length == 1) {
out += 'property ' + (it.util.escapeQuotes($deps[0])) + ' is';
} else {
out += 'properties ' + (it.util.escapeQuotes($deps.join(", "))) + ' are';
}
out += ' required when property ' + (it.util.escapeQuotes($property)) + ' is present\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } ';
if ($breakOnError) {
$closingBraces += '}';
out += ' else { ';
}
out += ' }';
}
for (var $property in $schemaDeps) {
var $sch = $schemaDeps[$property];
if (it.util.schemaHasRules($sch, it.RULES.all)) {
out += ' valid' + ($it.level) + ' = true; if (' + ($data) + '[\'' + ($property) + '\'] !== undefined) { ';
$it.schema = $sch;
$it.schemaPath = $schemaPath + it.util.getProperty($property);
out += ' ' + (it.validate($it)) + ' } ';
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
}
if ($breakOnError) {
out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {';
}
out = it.util.cleanUpCode(out);
return out;
}

View File

@ -1,32 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['enum'],
$schemaPath = it.schemaPath + '.' + 'enum',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $i = 'i' + $lvl;
out += 'var enumSchema' + ($lvl) + ' = validate.schema' + ($schemaPath) + ' , ' + ($valid) + ' = false;for (var ' + ($i) + '=0; ' + ($i) + '<enumSchema' + ($lvl) + '.length; ' + ($i) + '++) if (equal(' + ($data) + ', enumSchema' + ($lvl) + '[' + ($i) + '])) { ' + ($valid) + ' = true; break; } if (!' + ($valid) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('enum') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be equal to one of values\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('enum') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be equal to one of values\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' }';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,44 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['format'],
$schemaPath = it.schemaPath + '.' + 'format',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $format = it.formats[$schema];
if (it.opts.format !== false && $format) {
out += ' if (! ';
if (typeof $format == 'function') {
out += ' formats' + (it.util.getProperty($schema)) + ' (' + ($data) + ') ';
} else {
out += ' formats' + (it.util.getProperty($schema)) + ' .test(' + ($data) + ') ';
}
out += ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('format') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should match format ' + (it.util.escapeQuotes($schema)) + '\' ';
if (it.opts.verbose) {
out += ', schema: \'' + (it.util.escapeQuotes($schema)) + '\', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('format') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should match format ' + (it.util.escapeQuotes($schema)) + '\' ';
if (it.opts.verbose) {
out += ', schema: \'' + (it.util.escapeQuotes($schema)) + '\', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } ';
if ($breakOnError) {
out += ' else { ';
}
} else {
if ($breakOnError) {
out += ' if (true) { ';
}
}
return out;
}

View File

@ -1,114 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['items'],
$schemaPath = it.schemaPath + '.' + 'items',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $it = it.util.copy(it),
$closingBraces = '';
$it.level++;
var $dataNxt = $it.dataLevel = it.dataLevel + 1,
$nextData = 'data' + $dataNxt;
out += 'var ' + ($errs) + ' = errors;var ' + ($valid) + ';';
if (Array.isArray($schema)) {
var $additionalItems = it.schema.additionalItems;
if ($additionalItems === false) {
out += ' ' + ($valid) + ' = ' + ($data) + '.length <= ' + ($schema.length) + '; if (!' + ($valid) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('additionalItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have more than ' + ($schema.length) + ' items\' ';
if (it.opts.verbose) {
out += ', schema: false, data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('additionalItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have more than ' + ($schema.length) + ' items\' ';
if (it.opts.verbose) {
out += ', schema: false, data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } ';
if ($breakOnError) {
$closingBraces += '}';
out += ' else { ';
}
}
var arr1 = $schema;
if (arr1) {
var $sch, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$sch = arr1[$i += 1];
if (it.util.schemaHasRules($sch, it.RULES.all)) {
out += ' valid' + ($it.level) + ' = true; if (' + ($data) + '.length > ' + ($i) + ') { ';
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errorPath = (it.errorPath + ' + "[' + $i + ']"').replace('" + "', '');
var $passData = $data + '[' + $i + ']';
var $code = it.validate($it);
if (it.util.varOccurences($code, $nextData) < 2) {
out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' ';
} else {
out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' ';
}
out += ' } ';
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
}
}
if (typeof $additionalItems == 'object' && it.util.schemaHasRules($additionalItems, it.RULES.all)) {
$it.schema = $additionalItems;
$it.schemaPath = it.schemaPath + '.additionalItems';
out += ' valid' + ($it.level) + ' = true; if (' + ($data) + '.length > ' + ($schema.length) + ') { for (var i' + ($lvl) + ' = ' + ($schema.length) + '; i' + ($lvl) + ' < ' + ($data) + '.length; i' + ($lvl) + '++) { ';
$it.errorPath = (it.errorPath + ' + "[" + i' + $lvl + ' + "]"').replace('" + "', '');
var $passData = $data + '[i' + $lvl + ']';
var $code = it.validate($it);
if (it.util.varOccurences($code, $nextData) < 2) {
out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' ';
} else {
out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' ';
}
if ($breakOnError) {
out += ' if (!valid' + ($it.level) + ') break; ';
}
out += ' } } ';
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
} else if (it.util.schemaHasRules($schema, it.RULES.all)) {
$it.schema = $schema;
$it.schemaPath = $schemaPath;
out += ' for (var i' + ($lvl) + ' = ' + (0) + '; i' + ($lvl) + ' < ' + ($data) + '.length; i' + ($lvl) + '++) { ';
$it.errorPath = (it.errorPath + ' + "[" + i' + $lvl + ' + "]"').replace('" + "', '');
var $passData = $data + '[i' + $lvl + ']';
var $code = it.validate($it);
if (it.util.varOccurences($code, $nextData) < 2) {
out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' ';
} else {
out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' ';
}
if ($breakOnError) {
out += ' if (!valid' + ($it.level) + ') break; ';
}
out += ' } ';
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
if ($breakOnError) {
out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {';
}
out = it.util.cleanUpCode(out);
return out;
}

View File

@ -1,31 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['maxItems'],
$schemaPath = it.schemaPath + '.' + 'maxItems',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
out += 'if (' + ($data) + '.length > ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('maxItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have more than ' + ($schema) + ' items\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('maxItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have more than ' + ($schema) + ' items\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,37 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['maxLength'],
$schemaPath = it.schemaPath + '.' + 'maxLength',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
out += 'if ( ';
if (it.opts.unicode === false) {
out += ' ' + ($data) + '.length ';
} else {
out += ' ucs2length(' + ($data) + ') ';
}
out += ' > ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('maxLength') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT be longer than ' + ($schema) + ' characters\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('maxLength') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT be longer than ' + ($schema) + ' characters\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,31 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['maxProperties'],
$schemaPath = it.schemaPath + '.' + 'maxProperties',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
out += 'if (Object.keys(' + ($data) + ').length > ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('maxProperties') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have more than ' + ($schema) + ' properties\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('maxProperties') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have more than ' + ($schema) + ' properties\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,34 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['maximum'],
$schemaPath = it.schemaPath + '.' + 'maximum',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $exclusive = it.schema.exclusiveMaximum === true,
$op = $exclusive ? '<' : '<=',
$notOp = $exclusive ? '>=' : '>';
out += 'if (' + ($data) + ' ' + ($notOp) + ' ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('maximum') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be ' + ($op) + ' ' + ($schema) + '\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('maximum') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be ' + ($op) + ' ' + ($schema) + '\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,31 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['minItems'],
$schemaPath = it.schemaPath + '.' + 'minItems',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
out += 'if (' + ($data) + '.length < ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('minItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have less than ' + ($schema) + ' items\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('minItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have less than ' + ($schema) + ' items\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,37 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['minLength'],
$schemaPath = it.schemaPath + '.' + 'minLength',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
out += 'if ( ';
if (it.opts.unicode === false) {
out += ' ' + ($data) + '.length ';
} else {
out += ' ucs2length(' + ($data) + ') ';
}
out += ' < ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('minLength') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT be shorter than ' + ($schema) + ' characters\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('minLength') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT be shorter than ' + ($schema) + ' characters\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,31 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['minProperties'],
$schemaPath = it.schemaPath + '.' + 'minProperties',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
out += 'if (Object.keys(' + ($data) + ').length < ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('minProperties') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have less than ' + ($schema) + ' properties\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('minProperties') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT have less than ' + ($schema) + ' properties\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,34 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['minimum'],
$schemaPath = it.schemaPath + '.' + 'minimum',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $exclusive = it.schema.exclusiveMinimum === true,
$op = $exclusive ? '>' : '>=',
$notOp = $exclusive ? '<=' : '<';
out += 'if (' + ($data) + ' ' + ($notOp) + ' ' + ($schema) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('minimum') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be ' + ($op) + ' ' + ($schema) + '\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('minimum') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be ' + ($op) + ' ' + ($schema) + '\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,31 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['multipleOf'],
$schemaPath = it.schemaPath + '.' + 'multipleOf',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
out += 'var division' + ($lvl) + ' = ' + ($data) + ' / ' + ($schema) + ';if (' + ($data) + ' / ' + ($schema) + ' !== parseInt(division' + ($lvl) + ')) { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('multipleOf') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be multiple of ' + ($schema) + '\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('multipleOf') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should be multiple of ' + ($schema) + '\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,47 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['not'],
$schemaPath = it.schemaPath + '.' + 'not',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $it = it.util.copy(it),
$closingBraces = '';
$it.level++;
if (it.util.schemaHasRules($schema, it.RULES.all)) {
$it.schema = $schema;
$it.schemaPath = $schemaPath;
out += ' var ' + ($errs) + ' = errors; ' + (it.validate($it)) + ' if (valid' + ($it.level) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('not') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT be valid\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('not') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT be valid\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } ';
if (it.opts.allErrors) {
out += ' } ';
}
} else {
out += ' var err = { keyword: \'' + ('not') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should NOT be valid\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
if ($breakOnError) {
out += ' if (false) { ';
}
}
return out;
}

View File

@ -1,55 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['oneOf'],
$schemaPath = it.schemaPath + '.' + 'oneOf',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $it = it.util.copy(it),
$closingBraces = '';
$it.level++;
out += 'var ' + ($errs) + ' = errors;var prevValid' + ($lvl) + ' = false;var ' + ($valid) + ' = false;';
var arr1 = $schema;
if (arr1) {
var $sch, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$sch = arr1[$i += 1];
if (it.util.schemaHasRules($sch, it.RULES.all)) {
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
out += ' ' + (it.validate($it)) + ' ';
} else {
out += ' var valid' + ($it.level) + ' = true; ';
}
if ($i) {
out += ' if (valid' + ($it.level) + ' && prevValid' + ($lvl) + ') ' + ($valid) + ' = false; else { ';
$closingBraces += '}';
}
out += ' if (valid' + ($it.level) + ') ' + ($valid) + ' = prevValid' + ($lvl) + ' = true;';
}
}
out += '' + ($closingBraces) + 'if (!' + ($valid) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('oneOf') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should match exactly one schema in oneOf\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('oneOf') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should match exactly one schema in oneOf\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} else { errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; }';
if (it.opts.allErrors) {
out += ' } ';
}
return out;
}

View File

@ -1,32 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['pattern'],
$schemaPath = it.schemaPath + '.' + 'pattern',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
new RegExp($schema);
out += 'if (! /' + (it.util.escapeRegExp($schema)) + '/.test(' + ($data) + ') ) { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('pattern') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should match pattern "' + (it.util.escapeQuotes($schema)) + '"\' ';
if (it.opts.verbose) {
out += ', schema: \'' + (it.util.escapeQuotes($schema)) + '\', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('pattern') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'should match pattern "' + (it.util.escapeQuotes($schema)) + '"\' ';
if (it.opts.verbose) {
out += ', schema: \'' + (it.util.escapeQuotes($schema)) + '\', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@ -1,170 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['properties'],
$schemaPath = it.schemaPath + '.' + 'properties',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $it = it.util.copy(it),
$closingBraces = '';
$it.level++;
var $dataNxt = $it.dataLevel = it.dataLevel + 1,
$nextData = 'data' + $dataNxt;
var $pProperties = it.schema.patternProperties || {},
$pPropertyKeys = Object.keys($pProperties),
$aProperties = it.schema.additionalProperties,
$noAdditional = $aProperties === false,
$additionalIsSchema = typeof $aProperties == 'object' && Object.keys($aProperties).length,
$removeAdditional = it.opts.removeAdditional,
$checkAdditional = $noAdditional || $additionalIsSchema || $removeAdditional;
out += 'var ' + ($errs) + ' = errors;var valid' + ($it.level) + ' = true;';
if ($checkAdditional) {
out += ' var propertiesSchema' + ($lvl) + ' = validate.schema' + ($schemaPath) + ' || {}; for (var key' + ($lvl) + ' in ' + ($data) + ') { var isAdditional' + ($lvl) + ' = propertiesSchema' + ($lvl) + '[key' + ($lvl) + '] === undefined; ';
if ($pPropertyKeys.length) {
out += ' if (isAdditional' + ($lvl) + ') { ';
var arr1 = $pPropertyKeys;
if (arr1) {
var $pProperty, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$pProperty = arr1[$i += 1];
out += ' if (/' + (it.util.escapeRegExp($pProperty)) + '/.test(key' + ($lvl) + ')) isAdditional' + ($lvl) + ' = false; ';
if ($i < $pPropertyKeys.length - 1) {
out += ' else ';
}
}
}
out += ' } ';
}
out += ' if (isAdditional' + ($lvl) + ') { ';
if ($removeAdditional == 'all') {
out += ' delete ' + ($data) + '[key' + ($lvl) + ']; ';
} else {
var $currentErrorPath = it.errorPath;
it.errorPath = (it.errorPath + ' + "[\'" + key' + $lvl + ' + "\']"').replace('" + "', '');
if ($noAdditional) {
if ($removeAdditional) {
out += ' delete ' + ($data) + '[key' + ($lvl) + ']; ';
} else {
out += ' valid' + ($it.level) + ' = false; ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('additionalProperties') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'additional properties NOT allowed\' ';
if (it.opts.verbose) {
out += ', schema: false, data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('additionalProperties') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'additional properties NOT allowed\' ';
if (it.opts.verbose) {
out += ', schema: false, data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
if ($breakOnError) {
out += ' break; ';
}
}
} else if ($additionalIsSchema) {
if ($removeAdditional == 'failing') {
out += ' var ' + ($errs) + ' = errors; ';
}
$it.schema = $aProperties;
$it.schemaPath = it.schemaPath + '.additionalProperties';
$it.errorPath = it.errorPath;
var $passData = $data + '[key' + $lvl + ']';
var $code = it.validate($it);
if (it.util.varOccurences($code, $nextData) < 2) {
out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' ';
} else {
out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' ';
}
if ($removeAdditional == 'failing') {
out += ' if (!valid' + ($it.level) + ') { errors = ' + ($errs) + '; if (validate.errors !== null) { if (errors) validate.errors.length = errors; else validate.errors = null; } delete ' + ($data) + '[key' + ($lvl) + ']; } ';
} else {
if ($breakOnError) {
out += ' if (!valid' + ($it.level) + ') break; ';
}
}
}
it.errorPath = $currentErrorPath;
}
out += ' } } ';
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
if ($schema) {
for (var $propertyKey in $schema) {
var $sch = $schema[$propertyKey];
if (it.util.schemaHasRules($sch, it.RULES.all)) {
$it.schema = $sch;
var $prop = it.util.getProperty($propertyKey),
$passData = $data + $prop;
$it.schemaPath = $schemaPath + $prop;
$it.errorPath = (it.errorPath + ' + "' + $prop + '"').replace('" + "', '');
var $code = it.validate($it);
if (it.util.varOccurences($code, $nextData) < 2) {
$code = it.util.varReplace($code, $nextData, $passData);
var $useData = $passData;
} else {
var $useData = $nextData;
out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ';
}
if ($breakOnError) {
out += ' if (' + ($useData) + ' === undefined) { valid' + ($it.level) + ' = true; } else { ';
} else {
out += ' if (' + ($useData) + ' !== undefined) { ';
}
out += ' ' + ($code) + ' } ';
}
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
}
var arr2 = $pPropertyKeys;
if (arr2) {
var $pProperty, i2 = -1,
l2 = arr2.length - 1;
while (i2 < l2) {
$pProperty = arr2[i2 += 1];
var $sch = $pProperties[$pProperty];
if (it.util.schemaHasRules($sch, it.RULES.all)) {
$it.schema = $sch;
$it.schemaPath = it.schemaPath + '.patternProperties' + it.util.getProperty($pProperty);
out += ' for (var key' + ($lvl) + ' in ' + ($data) + ') { if (/' + (it.util.escapeRegExp($pProperty)) + '/.test(key' + ($lvl) + ')) { ';
$it.errorPath = (it.errorPath + ' + "[\'" + key' + $lvl + ' + "\']"').replace('" + "', '');
var $passData = $data + '[key' + $lvl + ']';
var $code = it.validate($it);
if (it.util.varOccurences($code, $nextData) < 2) {
out += ' ' + (it.util.varReplace($code, $nextData, $passData)) + ' ';
} else {
out += ' var ' + ($nextData) + ' = ' + ($passData) + '; ' + ($code) + ' ';
}
if ($breakOnError) {
out += ' if (!valid' + ($it.level) + ') break; ';
}
out += ' } ';
if ($breakOnError) {
out += ' else valid' + ($it.level) + ' = true; ';
}
out += ' } ';
if ($breakOnError) {
out += ' if (valid' + ($it.level) + ') { ';
$closingBraces += '}';
}
}
}
}
if ($breakOnError) {
out += ' ' + ($closingBraces) + ' if (' + ($errs) + ' == errors) {';
}
out = it.util.cleanUpCode(out);
return out;
}

View File

@ -46,13 +46,13 @@ module.exports = function anonymous(it) {
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('$ref') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'can\\\'t resolve reference ' + (it.util.escapeQuotes($schema)) + '\' ';
if (it.opts.verbose) {
out += ', schema: \'' + (it.util.escapeQuotes($schema)) + '\', data: ' + ($data);
out += ', schema: ' + (it.util.toQuotedString($schema)) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('$ref') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'can\\\'t resolve reference ' + (it.util.escapeQuotes($schema)) + '\' ';
if (it.opts.verbose) {
out += ', schema: \'' + (it.util.escapeQuotes($schema)) + '\', data: ' + ($data);
out += ', schema: ' + (it.util.toQuotedString($schema)) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}

View File

@ -1,103 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['required'],
$schemaPath = it.schemaPath + '.' + 'required',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
var $currentErrorPath = it.errorPath;
if ($breakOnError) {
out += ' var missing' + ($lvl) + '; ';
if ($schema.length <= 20) {
out += ' if ( ';
var arr1 = $schema;
if (arr1) {
var $property, $i = -1,
l1 = arr1.length - 1;
while ($i < l1) {
$property = arr1[$i += 1];
if ($i) {
out += ' || ';
}
var $prop = it.util.getProperty($property);
out += ' ( ' + ($data) + ($prop) + ' === undefined && (missing' + ($lvl) + ' = \'' + (it.util.escapeQuotes($prop)) + '\') ) ';
}
}
out += ') { ';
var $propertyPath = ' + missing' + $lvl,
$missingProperty = '\'' + $propertyPath + ' + \'';
it.errorPath = $currentErrorPath + $propertyPath;
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('required') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'property ' + ($missingProperty) + ' is required\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('required') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'property ' + ($missingProperty) + ' is required\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } else { ';
} else {
out += ' var schema' + ($lvl) + ' = validate.schema' + ($schemaPath) + '; ';
var $i = 'i' + $lvl,
$propertyPath = ' + schema' + $lvl + '[' + $i + '] + ',
$missingProperty = '\' + "\'"' + $propertyPath + '"\'" + \'';
it.errorPath = ($currentErrorPath + ' + "[\'"' + $propertyPath + '"\']"').replace('" + "', '');
out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < schema' + ($lvl) + '.length; ' + ($i) + '++) { var ' + ($valid) + ' = ' + ($data) + '[schema' + ($lvl) + '[' + ($i) + ']] !== undefined; if (!' + ($valid) + ') break; } if (!' + ($valid) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('required') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'property ' + ($missingProperty) + ' is required\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('required') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'property ' + ($missingProperty) + ' is required\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } else { ';
}
} else {
if ($schema.length <= 10) {
var arr2 = $schema;
if (arr2) {
var $property, $i = -1,
l2 = arr2.length - 1;
while ($i < l2) {
$property = arr2[$i += 1];
var $prop = it.util.getProperty($property),
$missingProperty = it.util.escapeQuotes($prop);
it.errorPath = ($currentErrorPath + ' + \'' + $missingProperty + '\'').replace('" + "', '');
out += ' if (' + ($data) + ($prop) + ' === undefined) { var err = { keyword: \'' + ('required') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'property ' + ($missingProperty) + ' is required\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } ';
}
}
} else {
out += ' var schema' + ($lvl) + ' = validate.schema' + ($schemaPath) + '; ';
var $i = 'i' + $lvl,
$propertyPath = ' + schema' + $lvl + '[' + $i + '] + ',
$missingProperty = '\' + "\'"' + $propertyPath + '"\'" + \'';
it.errorPath = ($currentErrorPath + ' + "[\'"' + $propertyPath + '"\']"').replace('" + "', '');
out += ' for (var ' + ($i) + ' = 0; ' + ($i) + ' < schema' + ($lvl) + '.length; ' + ($i) + '++) { if (' + ($data) + '[schema' + ($lvl) + '[' + ($i) + ']] === undefined) { var err = { keyword: \'' + ('required') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'property ' + ($missingProperty) + ' is required\' ';
if (it.opts.verbose) {
out += ', schema: validate.schema' + ($schemaPath) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; } } ';
}
}
it.errorPath = $currentErrorPath;
return out;
}

View File

@ -1,37 +0,0 @@
'use strict';
module.exports = function anonymous(it) {
var out = ' ';
var $lvl = it.level,
$dataLvl = it.dataLevel,
$schema = it.schema['uniqueItems'],
$schemaPath = it.schemaPath + '.' + 'uniqueItems',
$breakOnError = !it.opts.allErrors;
var $data = 'data' + ($dataLvl || ''),
$valid = 'valid' + $lvl,
$errs = 'errs' + $lvl;
if ($schema && it.opts.uniqueItems !== false) {
out += ' var ' + ($valid) + ' = true; if (' + ($data) + '.length > 1) { var i = ' + ($data) + '.length, j; outer: for (;i--;) { for (j = i; j--;) { if (equal(' + ($data) + '[i], ' + ($data) + '[j])) { ' + ($valid) + ' = false; break outer; } } } } if (!' + ($valid) + ') { ';
if (it.wasTop && $breakOnError) {
out += ' validate.errors = [ { keyword: \'' + ('uniqueItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'items ## \' + j + \' and \' + i + \' are duplicate\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }]; return false; ';
} else {
out += ' var err = { keyword: \'' + ('uniqueItems') + '\', dataPath: (dataPath || \'\') + ' + (it.errorPath) + ', message: \'items ## \' + j + \' and \' + i + \' are duplicate\' ';
if (it.opts.verbose) {
out += ', schema: ' + ($schema) + ', data: ' + ($data);
}
out += ' }; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += ' } ';
if ($breakOnError) {
out += ' else { ';
}
} else {
if ($breakOnError) {
out += ' if (true) { ';
}
}
return out;
}

View File

@ -1,12 +1,21 @@
{
"name": "ajv",
"version": "1.0.0",
"version": "1.1.1",
"description": "Another JSON Schema Validator",
"main": "lib/ajv.js",
"files": [
"lib/",
"LICENSE"
],
"scripts": {
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "istanbul cover -x '**/spec/**' node_modules/mocha/bin/_mocha -- spec/*.spec.js -R spec",
"test": "npm run test-cov"
"bundle": "browserify -r ./lib/ajv.js:ajv -o ajv.bundle.js",
"build": "node scripts/compile-dots.js",
"test-browser": "scripts/prepare-tests && karma start --single-run --browsers PhantomJS",
"test": "npm run build && npm run test-cov && npm run test-browser",
"prepublish": "npm run build",
"watch": "watch 'npm run build' ./lib/dot"
},
"repository": {
"type": "git",
@ -27,6 +36,7 @@
"json-stable-stringify": "^1.0.0"
},
"devDependencies": {
"browserify": "^11.0.1",
"chai": "^3.0.0",
"dot": "^1.0.3",
"glob": "^5.0.10",
@ -36,8 +46,11 @@
"karma": "^0.13.3",
"karma-chrome-launcher": "^0.2.0",
"karma-mocha": "^0.2.0",
"karma-phantomjs-launcher": "^0.2.1",
"karma-sauce-launcher": "^0.2.14",
"mocha": "^2.2.5",
"phantomjs": "^1.9.18",
"pre-commit": "^1.1.1",
"require-globify": "^1.2.1",
"watch": "^0.16.0"
}

View File

@ -9,7 +9,10 @@ var glob = require('glob')
var defs = fs.readFileSync(path.join(__dirname, '../lib/dot/definitions.def'));
var files = glob.sync('../lib/dot/*.jst', { cwd: __dirname });
console.log('\n\n' + new Date + '\nCompiling:');
var dotjsPath = path.join(__dirname, '../lib/dotjs');
try { fs.mkdirSync(dotjsPath); } catch(e) {}
console.log('\n\nCompiling:');
files.forEach(function (f) {
var template = fs.readFileSync(path.join(__dirname, f));
@ -18,7 +21,7 @@ files.forEach(function (f) {
code = code.replace(/out\s*\+=\s*'\s*';/g, '');
code = beautify(code, { indent_size: 2 }) + '\n';
var targetFile = f.replace('../lib/dot', '').replace('.jst', '.js')
, targetPath = path.join(__dirname, '../lib/dotjs', targetFile);
, targetPath = path.join(dotjsPath, targetFile);
fs.writeFileSync(targetPath, code);
console.log('compiled', targetFile);
});

View File

@ -6,11 +6,12 @@ var Ajv = require(typeof window == 'object' ? 'ajv' : '../lib/ajv')
describe('Validation errors', function () {
var ajv, fullAjv;
var ajv, ajvJP, fullAjv;
beforeEach(function() {
ajv = Ajv();
fullAjv = Ajv({ allErrors: true, beautify: true });
ajvJP = Ajv({ jsonPointers: true });
fullAjv = Ajv({ allErrors: true, jsonPointers: true });
});
it('error should include dataPath', function() {
@ -50,15 +51,20 @@ describe('Validation errors', function () {
shouldBeInvalid(validate, invalidData);
shouldBeError(validate.errors[0], 'additionalProperties', "['baz']");
var validateJP = ajvJP.compile(schema);
shouldBeValid(validateJP, data);
shouldBeInvalid(validateJP, invalidData);
shouldBeError(validateJP.errors[0], 'additionalProperties', "/baz");
var fullValidate = fullAjv.compile(schema);
shouldBeValid(fullValidate, data);
shouldBeInvalid(fullValidate, invalidData, 2);
shouldBeError(fullValidate.errors[0], 'additionalProperties', "['baz']");
shouldBeError(fullValidate.errors[1], 'additionalProperties', "['quux']");
shouldBeError(fullValidate.errors[0], 'additionalProperties', '/baz');
shouldBeError(fullValidate.errors[1], 'additionalProperties', '/quux');
fullValidate.errors
.filter(function(err) { return err.keyword == 'additionalProperties'; })
.map(function(err) { return err.dataPath.slice(2,-2); })
.map(function(err) { return fullAjv.opts.jsonPointers ? err.dataPath.substr(1) : err.dataPath.slice(2,-2); })
.forEach(function(p) { delete invalidData[p]; });
invalidData .should.eql({ foo: 1, bar: 2 });
@ -81,13 +87,20 @@ describe('Validation errors', function () {
shouldBeInvalid(validate, invalidData2);
shouldBeError(validate.errors[0], 'required', '.foo', 'property .foo is required');
var validateJP = ajvJP.compile(schema);
shouldBeValid(validateJP, data);
shouldBeInvalid(validateJP, invalidData1);
shouldBeError(validateJP.errors[0], 'required', '/bar', 'property bar is required');
shouldBeInvalid(validateJP, invalidData2);
shouldBeError(validateJP.errors[0], 'required', '/foo', 'property foo is required');
var fullValidate = fullAjv.compile(schema);
shouldBeValid(fullValidate, data);
shouldBeInvalid(fullValidate, invalidData1);
shouldBeError(fullValidate.errors[0], 'required', '.bar', 'property .bar is required');
shouldBeError(fullValidate.errors[0], 'required', '/bar', 'property .bar is required');
shouldBeInvalid(fullValidate, invalidData2, 2);
shouldBeError(fullValidate.errors[0], 'required', '.foo', 'property .foo is required');
shouldBeError(fullValidate.errors[1], 'required', '.baz', 'property .baz is required');
shouldBeError(fullValidate.errors[0], 'required', '/foo', 'property .foo is required');
shouldBeError(fullValidate.errors[1], 'required', '/baz', 'property .baz is required');
});
@ -112,18 +125,26 @@ describe('Validation errors', function () {
shouldBeInvalid(validate, invalidData2);
shouldBeError(validate.errors[0], 'required', "['2']", "property '2' is required");
var validateJP = ajvJP.compile(schema);
shouldBeValid(validateJP, data);
shouldBeInvalid(validateJP, invalidData1);
shouldBeError(validateJP.errors[0], 'required', "/1", "property '1' is required");
shouldBeInvalid(validateJP, invalidData2);
shouldBeError(validateJP.errors[0], 'required', "/2", "property '2' is required");
var fullValidate = fullAjv.compile(schema);
shouldBeValid(fullValidate, data);
shouldBeInvalid(fullValidate, invalidData1);
shouldBeError(fullValidate.errors[0], 'required', "['1']", "property '1' is required");
shouldBeError(fullValidate.errors[0], 'required', '/1', "property '1' is required");
shouldBeInvalid(fullValidate, invalidData2, 2);
shouldBeError(fullValidate.errors[0], 'required', "['2']", "property '2' is required");
shouldBeError(fullValidate.errors[1], 'required', "['98']", "property '98' is required");
shouldBeError(fullValidate.errors[0], 'required', '/2', "property '2' is required");
shouldBeError(fullValidate.errors[1], 'required', '/98', "property '98' is required");
});
function testSchema1(schema) {
_testSchema1(ajv, schema);
_testSchema1(ajvJP, schema);
_testSchema1(fullAjv, schema)
}
@ -135,7 +156,7 @@ describe('Validation errors', function () {
var validate = ajv.compile(schema);
shouldBeValid(validate, data);
shouldBeInvalid(validate, invalidData);
shouldBeError(validate.errors[0], 'type', '.foo');
shouldBeError(validate.errors[0], 'type', ajv.opts.jsonPointers ? '/foo' : '.foo');
}

View File

@ -7,7 +7,7 @@ var jsonSchemaTest = require('json-schema-test')
var Ajv = require(typeof window == 'object' ? 'ajv' : '../lib/ajv')
, ajv = Ajv({ beautify: true })
, verboseAjv = Ajv({ verbose: true, beautify: true })
, fullAjv = Ajv({ allErrors: true, verbose: true, format: 'full', beautify: true });
, fullAjv = Ajv({ allErrors: true, verbose: true, format: 'full', beautify: true, jsonPointers: true });
var remoteRefs = {
// for JSON-Schema-Test-Suite

View File

@ -0,0 +1,21 @@
[
{
"description": "use latest json schema as v4 (#33)",
"schema": {
"$schema": "http://json-schema.org/schema",
"type": "object",
"properties": {
"username": {
"type": "string"
}
}
},
"tests": [
{
"description": "empty object",
"data": {},
"valid": true
}
]
}
]