diff --git a/.gitignore b/.gitignore index 9312e88..4b0dc57 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ node_modules .DS_Store +# Compiled templates +lib/dotjs/*.js + # Browserified tests .browser diff --git a/README.md b/README.md index b106f7d..fa5b44e 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/bin/compile-dots b/bin/compile-dots deleted file mode 100755 index 6a36700..0000000 --- a/bin/compile-dots +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -node ./bin/compile-dots.js diff --git a/bin/create-bundle b/bin/create-bundle deleted file mode 100755 index a173b26..0000000 --- a/bin/create-bundle +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -browserify -r ./lib/ajv.js:ajv -o ajv.bundle.js diff --git a/bin/git-hook b/bin/git-hook deleted file mode 100755 index 176d477..0000000 --- a/bin/git-hook +++ /dev/null @@ -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 diff --git a/bin/pre-commit b/bin/pre-commit deleted file mode 100755 index 34b35a3..0000000 --- a/bin/pre-commit +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -set -e - -bin/compile-dots -npm run test-spec diff --git a/bin/watch-dots b/bin/watch-dots deleted file mode 100755 index 919f379..0000000 --- a/bin/watch-dots +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env bash -./node_modules/.bin/watch 'node bin/compile-dots.js' ./lib/dot \ No newline at end of file diff --git a/lib/ajv.js b/lib/ajv.js index 0daf525..d5849d0 100644 --- a/lib/ajv.js +++ b/lib/ajv.js @@ -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; diff --git a/lib/compile/index.js b/lib/compile/index.js index 2e05318..aaf6887 100644 --- a/lib/compile/index.js +++ b/lib/compile/index.js @@ -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 {{=$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 + ']'; }} diff --git a/lib/dot/pattern.jst b/lib/dot/pattern.jst index b314518..a0db8ad 100644 --- a/lib/dot/pattern.jst +++ b/lib/dot/pattern.jst @@ -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 { {{?}} diff --git a/lib/dot/properties.jst b/lib/dot/properties.jst index 69e5cc3..00182dd 100644 --- a/lib/dot/properties.jst +++ b/lib/dot/properties.jst @@ -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 + ']'; }} diff --git a/lib/dot/required.jst b/lib/dot/required.jst index 1cd73c1..7272d1e 100644 --- a/lib/dot/required.jst +++ b/lib/dot/required.jst @@ -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' }} diff --git a/lib/dotjs/README.md b/lib/dotjs/README.md index 5e0f434..4d99484 100644 --- a/lib/dotjs/README.md +++ b/lib/dotjs/README.md @@ -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. diff --git a/lib/dotjs/allOf.js b/lib/dotjs/allOf.js deleted file mode 100644 index d9f16cd..0000000 --- a/lib/dotjs/allOf.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/anyOf.js b/lib/dotjs/anyOf.js deleted file mode 100644 index 6ecfec9..0000000 --- a/lib/dotjs/anyOf.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/dependencies.js b/lib/dotjs/dependencies.js deleted file mode 100644 index a7275cc..0000000 --- a/lib/dotjs/dependencies.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/enum.js b/lib/dotjs/enum.js deleted file mode 100644 index 09646d6..0000000 --- a/lib/dotjs/enum.js +++ /dev/null @@ -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) + ' ' + ($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; -} diff --git a/lib/dotjs/maxItems.js b/lib/dotjs/maxItems.js deleted file mode 100644 index 3a15542..0000000 --- a/lib/dotjs/maxItems.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/maxLength.js b/lib/dotjs/maxLength.js deleted file mode 100644 index 1bc7bd7..0000000 --- a/lib/dotjs/maxLength.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/maxProperties.js b/lib/dotjs/maxProperties.js deleted file mode 100644 index 487b0cd..0000000 --- a/lib/dotjs/maxProperties.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/maximum.js b/lib/dotjs/maximum.js deleted file mode 100644 index 28d76b2..0000000 --- a/lib/dotjs/maximum.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/minItems.js b/lib/dotjs/minItems.js deleted file mode 100644 index 77d46f7..0000000 --- a/lib/dotjs/minItems.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/minLength.js b/lib/dotjs/minLength.js deleted file mode 100644 index 2ca1800..0000000 --- a/lib/dotjs/minLength.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/minProperties.js b/lib/dotjs/minProperties.js deleted file mode 100644 index ac9dcb4..0000000 --- a/lib/dotjs/minProperties.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/minimum.js b/lib/dotjs/minimum.js deleted file mode 100644 index ecf8c15..0000000 --- a/lib/dotjs/minimum.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/multipleOf.js b/lib/dotjs/multipleOf.js deleted file mode 100644 index ff1401f..0000000 --- a/lib/dotjs/multipleOf.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/not.js b/lib/dotjs/not.js deleted file mode 100644 index 3a2e7a1..0000000 --- a/lib/dotjs/not.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/oneOf.js b/lib/dotjs/oneOf.js deleted file mode 100644 index e2bc4c8..0000000 --- a/lib/dotjs/oneOf.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/pattern.js b/lib/dotjs/pattern.js deleted file mode 100644 index 7c7ec43..0000000 --- a/lib/dotjs/pattern.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/properties.js b/lib/dotjs/properties.js deleted file mode 100644 index b86d749..0000000 --- a/lib/dotjs/properties.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/ref.js b/lib/dotjs/ref.js index 0b2498d..3edbc36 100644 --- a/lib/dotjs/ref.js +++ b/lib/dotjs/ref.js @@ -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++; '; } diff --git a/lib/dotjs/required.js b/lib/dotjs/required.js deleted file mode 100644 index a36be64..0000000 --- a/lib/dotjs/required.js +++ /dev/null @@ -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; -} diff --git a/lib/dotjs/uniqueItems.js b/lib/dotjs/uniqueItems.js deleted file mode 100644 index d099169..0000000 --- a/lib/dotjs/uniqueItems.js +++ /dev/null @@ -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; -} diff --git a/package.json b/package.json index b95d749..98f7082 100644 --- a/package.json +++ b/package.json @@ -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" } diff --git a/bin/compile-dots.js b/scripts/compile-dots.js similarity index 81% rename from bin/compile-dots.js rename to scripts/compile-dots.js index b582ea0..e8e6452 100644 --- a/bin/compile-dots.js +++ b/scripts/compile-dots.js @@ -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); }); diff --git a/bin/prepare-tests b/scripts/prepare-tests similarity index 100% rename from bin/prepare-tests rename to scripts/prepare-tests diff --git a/spec/errors.spec.js b/spec/errors.spec.js index 4040cac..1d09902 100644 --- a/spec/errors.spec.js +++ b/spec/errors.spec.js @@ -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'); } diff --git a/spec/json-schema.spec.js b/spec/json-schema.spec.js index 333f267..91e4aea 100644 --- a/spec/json-schema.spec.js +++ b/spec/json-schema.spec.js @@ -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 diff --git a/spec/tests/issues/33_json_schema_latest.json b/spec/tests/issues/33_json_schema_latest.json new file mode 100644 index 0000000..1677411 --- /dev/null +++ b/spec/tests/issues/33_json_schema_latest.json @@ -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 + } + ] + } +]