diff --git a/README.md b/README.md index c993fe7..702f639 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ One of the fastest JSON Schema validators for node.js and browser. It uses precompiled [doT templates](https://github.com/olado/doT) to generate super-fast validating functions. - [![Build Status](https://travis-ci.org/epoberezkin/ajv.svg?branch=master)](https://travis-ci.org/epoberezkin/ajv) [![npm version](https://badge.fury.io/js/ajv.svg)](http://badge.fury.io/js/ajv) + ## JSON Schema standard ajv implements full [JSON Schema draft 4](http://json-schema.org/) standard: @@ -152,8 +152,9 @@ Returns the text with all errors in a String. Options can have these properties: - _verbose_: include the reference to the part of the schema and validated data in errors (false by default). - _format_: formats validation mode ('fast' by default). Pass 'full' for more correct and slow validation or `false` not to validate formats at all. E.g., 25:00:00 and 2015/14/33 will be invalid time and date in 'full' mode but it will be valid in 'fast' mode. - _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 absent (draft-4 meta-schema will be used) or can be a reference to any previously added schema. If the validation fails, the exception is thrown. Pass "log" in this option to log error instead of throwing exception. +- _validateSchema_: validate added/compiled schemas against meta-schema (true by default). `$schema` property in the schema can either be absent (draft-4 meta-schema will be used) or can be a reference to any previously added schema. 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. diff --git a/lib/dot/$ref.jst b/lib/dot/$ref.jst index 046832d..5379fef 100644 --- a/lib/dot/$ref.jst +++ b/lib/dot/$ref.jst @@ -31,7 +31,7 @@ {{??}} {{ var $refVal = it.resolveRef(it.baseId, $schema, it.rootId); }} {{? $refVal === undefined }} - {{ var $message = 'can\'t resolve reference ' + $schema; }} + {{ var $message = 'can\'t resolve reference ' + $schema + ' from id ' + it.baseId; }} {{? it.opts.missingRefs == 'fail' }} {{ console.log($message); }} {{# def.error:'$ref' }} diff --git a/lib/dotjs/$ref.js b/lib/dotjs/$ref.js index 5ffad19..358bf53 100644 --- a/lib/dotjs/$ref.js +++ b/lib/dotjs/$ref.js @@ -31,7 +31,7 @@ module.exports = function anonymous(it) { } else { var $refVal = it.resolveRef(it.baseId, $schema, it.rootId); if ($refVal === undefined) { - var $message = 'can\'t resolve reference ' + $schema; + var $message = 'can\'t resolve reference ' + $schema + ' from id ' + it.baseId; if (it.opts.missingRefs == 'fail') { console.log($message); if (it.wasTop && $breakOnError) { diff --git a/spec/json-schema.spec.js b/spec/json-schema.spec.js index d6c52bd..631b28d 100644 --- a/spec/json-schema.spec.js +++ b/spec/json-schema.spec.js @@ -17,9 +17,10 @@ var ONLY_FILES, SKIP_FILES; // 'refRemote', // 'definitions', // 'schemas/complex', -// 'schemas/basic' -// 'schemas/advanced' -// 'issues/12_restoring_root_after_resolve' +// 'schemas/basic', +// 'schemas/advanced', +// 'issues/12_restoring_root_after_resolve', +// 'issues/2_root_ref_in_ref' // ]; SKIP_FILES = [ @@ -35,9 +36,12 @@ var Ajv = require('../lib/ajv') , fullAjv = Ajv({ allErrors: true, verbose: true, format: 'full', beautify: true, _debug: DEBUG }); var remoteRefs = { + // for JSON-Schema-Test-Suite 'http://localhost:1234/integer.json': require('./JSON-Schema-Test-Suite/remotes/integer.json'), 'http://localhost:1234/subSchemas.json': require('./JSON-Schema-Test-Suite/remotes/subSchemas.json'), - 'http://localhost:1234/folder/folderInteger.json': require('./JSON-Schema-Test-Suite/remotes/folder/folderInteger.json') + 'http://localhost:1234/folder/folderInteger.json': require('./JSON-Schema-Test-Suite/remotes/folder/folderInteger.json'), + // for tests + 'http://localhost:1234/name.json': require('./remotes/name.json') }; for (var id in remoteRefs) { diff --git a/spec/remotes/name.json b/spec/remotes/name.json new file mode 100644 index 0000000..3fa219a --- /dev/null +++ b/spec/remotes/name.json @@ -0,0 +1,11 @@ +{ + "definitions": { + "orNull": { + "anyOf": [ + { "type": "null" }, + { "$ref": "#" } + ] + } + }, + "type": "string" +} diff --git a/spec/tests/issues/13_root_ref_in_ref_in_remote_ref.json b/spec/tests/issues/13_root_ref_in_ref_in_remote_ref.json new file mode 100644 index 0000000..2fb902e --- /dev/null +++ b/spec/tests/issues/13_root_ref_in_ref_in_remote_ref.json @@ -0,0 +1,38 @@ +[ + { + "skip": true, + "description": "root ref in remote ref (#13)", + "schema": { + "id": "http://localhost:1234/object", + "type": "object", + "properties": { + "name": { "$ref": "name.json#/definitions/orNull" } + } + }, + "tests": [ + { + "description": "string is valid", + "data": { + "name": "foo" + }, + "valid": true + }, + { + "description": "null is valid", + "data": { + "name": null + }, + "valid": true + }, + { + "description": "object is invalid", + "data": { + "name": { + "name": null + } + }, + "valid": false + } + ] + } +] diff --git a/spec/tests/issues/2_root_ref_in_ref.json b/spec/tests/issues/2_root_ref_in_ref.json index cb25005..341cce0 100644 --- a/spec/tests/issues/2_root_ref_in_ref.json +++ b/spec/tests/issues/2_root_ref_in_ref.json @@ -49,5 +49,92 @@ "valid": false } ] + }, + { + "description": "root ref in ref with anyOf (#2)", + "schema": { + "definitions": { + "orNull": { + "anyOf": [ + { "type": "null" }, + { "$ref": "#" } + ] + } + }, + "type": "object", + "properties": { + "name": { "type": "string" }, + "parent": { "$ref": "#/definitions/orNull" } + } + }, + "tests": [ + { + "description": "null parent is valid", + "data": { + "name": "foo", + "parent": null + }, + "valid": true + }, + { + "skip": false, + "description": "object parent is valid", + "data": { + "name": "foo", + "parent": { + "name": "bar", + "parent": null + } + }, + "valid": true + }, + { + "description": "object parent is valid", + "data": { + "name": "foo", + "parent": { + "name": "bar", + "parent": { + "name": "baz", + "parent": null + } + } + }, + "valid": true + }, + { + "description": "string parent is invalid", + "data": { + "name": "foo", + "parent": "buu" + }, + "valid": false + }, + { + "description": "string subparent is invalid", + "data": { + "name": "foo", + "parent": { + "name": "bar", + "parent": "baz" + } + }, + "valid": false + }, + { + "description": "string sub-subparent is invalid", + "data": { + "name": "foo", + "parent": { + "name": "bar", + "parent": { + "name": "baz", + "parent": "quux" + } + } + }, + "valid": false + } + ] } ]