Skip to content

Commit

Permalink
Merge pull request #89 from epoberezkin/switch
Browse files Browse the repository at this point in the history
Switch keyword
  • Loading branch information
Evgeny Poberezkin committed Dec 12, 2015
2 parents 7c7abbb + 1dc0f81 commit 16b6ee5
Show file tree
Hide file tree
Showing 35 changed files with 696 additions and 164 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ NB: [Upgrading to version 2.0.0](https://github.com/epoberezkin/ajv/releases/tag
- [error messages with parameters](#validation-errors) describing error reasons to allow creating custom error messages
- i18n error messages support with [ajv-i18n](https://github.com/epoberezkin/ajv-i18n) package (version >= 1.0.0)
- [filtering data](#filtering-data) from additional properties
- NEW: [custom keywords](#defining-custom-keywords)
- NEW: keywords `constant`, `contains`, `patternGroups`, `formatMaximum`/`formatMinimum` and `exclusiveFormatMaximum`/`exclusiveFormatMinimum` from [JSON-schema v5 proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals) with [option v5](#options)
- [custom keywords](#defining-custom-keywords)
- NEW: keywords `switch`, `constant`, `contains`, `patternGroups`, `formatMaximum`/`formatMinimum` and `exclusiveFormatMaximum`/`exclusiveFormatMinimum` from [JSON-schema v5 proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals) with [option v5](#options)
- NEW: [v5 meta-schema](https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#) for schemas using v5 keywords.

Currently ajv is the only validator that passes all the tests from [JSON Schema Test Suite](https://github.com/json-schema/JSON-Schema-Test-Suite) (according to [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark), apart from the test that requires that `1.0` is not an integer that is impossible to satisfy in JavaScript).

Expand Down Expand Up @@ -433,16 +434,18 @@ Adds meta schema that can be used to validate other schemas. That function shoul

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`.

With option `v5: true` meta-schema that includes v5 keywords also added. It is available at https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json


##### <a name="api-validateschema"></a>.validateSchema(Object schema) -&gt; Boolean

Validates schema. This method should be used to validate schemas rather than `validate` due to the inconsistency of `uri` format in JSON-Schema standart.

By default this method is called automatically when the schema is added, so you rarely need to use it directly.

If schema doesn't have `$schema` property it is validated against draft 4 meta-schema (option `meta` should not be false).
If schema doesn't have `$schema` property it is validated against draft 4 meta-schema (option `meta` should not be false) or against [v5 meta-schema](https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#) if option `v5` is true.

If schema has `$schema` property then the schema with this id (should be previously added) is used to validate passed schema.
If schema has `$schema` property then the schema with this id (that should be previously added) is used to validate passed schema.

Errors will be available at `ajv.errors`.

Expand Down Expand Up @@ -548,7 +551,7 @@ Defaults:
- _errorDataPath_: set `dataPath` to point to 'object' (default) or to 'property' (default behavior in versions before 2.0) when validating keywords `required`, `additionalProperties` and `dependencies`.
- _jsonPointers_: set `dataPath` propery of errors using [JSON Pointers](https://tools.ietf.org/html/rfc6901) instead of JavaScript property access notation.
- _messages_: Include human-readable messages in errors. `true` by default. `messages: false` can be added when custom messages are used (e.g. with [ajv-i18n](https://github.com/epoberezkin/ajv-i18n)).
- _v5_: add keywords `constant`, `contains`, `patternGroups`, `formatMaximum`/`formatMinimum` and `exclusiveFormatMaximum`/`exclusiveFormatMinimum` from [JSON-schema v5 proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals)
- _v5_: add keywords `switch`, `constant`, `contains`, `patternGroups`, `formatMaximum`/`formatMinimum` and `exclusiveFormatMaximum`/`exclusiveFormatMinimum` from [JSON-schema v5 proposals](https://github.com/json-schema/json-schema/wiki/v5-Proposals). With this option added schemas without `$schema` property are validated against [v5 meta-schema](https://raw.githubusercontent.com/epoberezkin/ajv/master/lib/refs/json-schema-v5.json#).


## Validation errors
Expand Down
2 changes: 1 addition & 1 deletion lib/ajv.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function Ajv(opts) {
* @return {Boolean}
*/
function validateSchema(schema, throwOrLogError) {
var $schema = schema.$schema || META_SCHEMA_ID;
var $schema = schema.$schema || (self.opts.v5 ? v5.META_SCHEMA_ID : META_SCHEMA_ID);
var currentUriFormat = self._formats.uri;
self._formats.uri = typeof currentUriFormat == 'function'
? SCHEMA_URI_FORMAT_FUNC
Expand Down
6 changes: 2 additions & 4 deletions lib/dot/allOf.jst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'allOf' }}
{{# def.setupNextLevel }}

Expand All @@ -11,10 +12,7 @@

{{= it.validate($it) }}

{{? $breakOnError }}
if (valid{{=$it.level}}) {
{{ $closingBraces += '}'; }}
{{?}}
{{# def.ifResultValid }}
{{?}}
{{~}}

Expand Down
7 changes: 2 additions & 5 deletions lib/dot/anyOf.jst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'anyOf' }}
{{# def.setupNextLevel }}

Expand Down Expand Up @@ -34,11 +35,7 @@
if (!{{=$valid}}) {
{{# def.addError:'anyOf' }}
} else {
errors = {{=$errs}};
if (vErrors !== null) {
if ({{=$errs}}) vErrors.length = {{=$errs}};
else vErrors = null;
}
{{# def.resetErrors }}
{{? it.opts.allErrors }} } {{?}}

{{# def.cleanUp }}
Expand Down
129 changes: 1 addition & 128 deletions lib/dot/definitions.def
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
, $schemaPath = it.schemaPath + '.' + _keyword
, $breakOnError = !it.opts.allErrors;


var $data = 'data' + ($dataLvl || '')
, $valid = 'valid' + $lvl
, $errs = 'errs' + $lvl;
, $errs = 'errs__' + $lvl;
}}
#}}

Expand Down Expand Up @@ -98,129 +97,3 @@


{{## def.cleanUpVarErrors: {{ out = it.util.cleanUpVarErrors(out); }} #}}


{{## def._error:_rule:
{
keyword: '{{=_rule}}'
, dataPath: (dataPath || '') + {{= it.errorPath }}
, schemaPath: "{{=$schemaPath}}"
, params: {{# def._errorParams[_rule] }}
{{? it.opts.messages !== false }}
, message: {{# def._errorMessages[_rule] }}
{{?}}
{{? it.opts.verbose }}
, schema: {{# def._errorSchemas[_rule] }}
, parentSchema: validate.schema{{=it.schemaPath}}
, data: {{=$data}}
{{?}}
}
#}}


{{## def.addError:_rule:
var err = {{# def._error:_rule }};
if (vErrors === null) vErrors = [err];
else vErrors.push(err);
errors++;
#}}


{{## def.error:_rule:
{{? !it.compositeRule && $breakOnError }}
validate.errors = [{{# def._error:_rule }}];
return false;
{{??}}
{{# def.addError:_rule }}
{{?}}
#}}


{{## def.checkError:_rule:
if (!{{=$valid}}) {
{{# def.error:_rule }}
}
#}}


{{## def._errorMessages = {
$ref: "'can\\\'t resolve reference {{=it.util.escapeQuotes($schema)}}'",
additionalItems: "'should NOT have more than {{=$schema.length}} items'",
additionalProperties: "'should NOT have additional properties'",
anyOf: "'should match some schema in anyOf'",
dependencies: "'should have {{? $deps.length == 1 }}property {{= it.util.escapeQuotes($deps[0]) }}{{??}}properties {{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}} when property {{= it.util.escapeQuotes($property) }} is present'",
enum: "'should be equal to one of values'",
format: "'should match format {{=it.util.escapeQuotes($schema)}}'",
maximum: "'should be {{=$op}} {{=$schema}}'",
minimum: "'should be {{=$op}} {{=$schema}}'",
maxItems: "'should NOT have more than {{=$schema}} items'",
minItems: "'should NOT have less than {{=$schema}} items'",
maxLength: "'should NOT be longer than {{=$schema}} characters'",
minLength: "'should NOT be shorter than {{=$schema}} characters'",
maxProperties: "'should NOT have more than {{=$schema}} properties'",
minProperties: "'should NOT have less than {{=$schema}} properties'",
multipleOf: "'should be multiple of {{=$schema}}'",
not: "'should NOT be valid'",
oneOf: "'should match exactly one schema in oneOf'",
pattern: "'should match pattern \"{{=it.util.escapeQuotes($schema)}}\"'",
required: "'{{? it.opts._errorDataPathProperty }}is a required property{{??}}should have required property \\'{{=$missingProperty}}\\'{{?}}'",
type: "'should be {{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}'",
uniqueItems: "'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)'",
custom: "'should pass \"{{=$rule.keyword}}\" keyword validation'",
patternGroups: "'should NOT have {{=$moreOrLess}} than {{=$limit}} properties matching pattern \"{{=it.util.escapeQuotes($pgProperty)}}\"'"
} #}}


{{## def._errorSchemas = {
$ref: "{{=it.util.toQuotedString($schema)}}",
additionalItems: "false",
additionalProperties: "false",
anyOf: "validate.schema{{=$schemaPath}}",
dependencies: "validate.schema{{=$schemaPath}}",
enum: "validate.schema{{=$schemaPath}}",
format: "{{=it.util.toQuotedString($schema)}}",
maximum: "{{=$schema}}",
minimum: "{{=$schema}}",
maxItems: "{{=$schema}}",
minItems: "{{=$schema}}",
maxLength: "{{=$schema}}",
minLength: "{{=$schema}}",
maxProperties: "{{=$schema}}",
minProperties: "{{=$schema}}",
multipleOf: "{{=$schema}}",
not: "validate.schema{{=$schemaPath}}",
oneOf: "validate.schema{{=$schemaPath}}",
pattern: "{{=it.util.toQuotedString($schema)}}",
required: "validate.schema{{=$schemaPath}}",
type: "{{? $isArray }}['{{= $typeSchema.join(\"','\") }}']{{??}}'{{=$typeSchema}}'{{?}}",
uniqueItems: "{{=$schema}}",
custom: "validate.schema{{=$schemaPath}}",
patternGroups: "validate.schema{{=$schemaPath}}"
} #}}


{{## def._errorParams = {
$ref: "{ ref: '{{=it.util.escapeQuotes($schema)}}' }",
additionalItems: "{ limit: {{=$schema.length}} }",
additionalProperties: "{ additionalProperty: '{{=$additionalProperty}}' }",
anyOf: "{}",
dependencies: "{ property: '{{= it.util.escapeQuotes($property) }}', missingProperty: '{{=$missingProperty}}', depsCount: {{=$deps.length}}, deps: '{{? $deps.length==1 }}{{= it.util.escapeQuotes($deps[0]) }}{{??}}{{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}}' }",
format: "{ format: '{{=it.util.escapeQuotes($schema)}}' }",
maximum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
minimum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
maxItems: "{ limit: {{=$schema}} }",
minItems: "{ limit: {{=$schema}} }",
maxLength: "{ limit: {{=$schema}} }",
minLength: "{ limit: {{=$schema}} }",
maxProperties: "{ limit: {{=$schema}} }",
minProperties: "{ limit: {{=$schema}} }",
multipleOf: "{ multipleOf: {{=$schema}} }",
not: "{}",
oneOf: "{}",
pattern: "{ pattern: '{{=it.util.escapeQuotes($schema)}}' }",
required: "{ missingProperty: '{{=$missingProperty}}' }",
type: "{ type: '{{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}' }",
uniqueItems: "{ i: i, j: j }",
custom: "{ keyword: '{{=$rule.keyword}}' }",
patternGroups: "{ reason: '{{=$reason}}', limit: {{=$limit}}, pattern: '{{=it.util.escapeQuotes($pgProperty)}}' }"
} #}}
1 change: 1 addition & 0 deletions lib/dot/dependencies.jst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.missing }}
{{# def.setup:'dependencies' }}
{{# def.setupNextLevel }}
Expand Down
1 change: 1 addition & 0 deletions lib/dot/enum.jst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'enum' }}

{{ var $i = 'i' + $lvl; }}
Expand Down
141 changes: 141 additions & 0 deletions lib/dot/errors.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
{{## def._error:_rule:
{{ 'istanbul ignore else'; }}
{{? it.createErrors !== false }}
{
keyword: '{{=_rule}}'
, dataPath: (dataPath || '') + {{= it.errorPath }}
, schemaPath: "{{=$schemaPath}}"
, params: {{# def._errorParams[_rule] }}
{{? it.opts.messages !== false }}
, message: {{# def._errorMessages[_rule] }}
{{?}}
{{? it.opts.verbose }}
, schema: {{# def._errorSchemas[_rule] }}
, parentSchema: validate.schema{{=it.schemaPath}}
, data: {{=$data}}
{{?}}
}
{{??}}
'{{=_rule}}'
{{?}}
#}}


{{## def.addError:_rule:
var err = {{# def._error:_rule }};
if (vErrors === null) vErrors = [err];
else vErrors.push(err);
errors++;
#}}


{{## def.error:_rule:
{{? !it.compositeRule && $breakOnError }}
validate.errors = [{{# def._error:_rule }}];
return false;
{{??}}
{{# def.addError:_rule }}
{{?}}
#}}


{{## def.checkError:_rule:
if (!{{=$valid}}) {
{{# def.error:_rule }}
}
#}}


{{## def.resetErrors:
errors = {{=$errs}};
if (vErrors !== null) {
if ({{=$errs}}) vErrors.length = {{=$errs}};
else vErrors = null;
}
#}}


{{## def._errorMessages = {
$ref: "'can\\\'t resolve reference {{=it.util.escapeQuotes($schema)}}'",
additionalItems: "'should NOT have more than {{=$schema.length}} items'",
additionalProperties: "'should NOT have additional properties'",
anyOf: "'should match some schema in anyOf'",
dependencies: "'should have {{? $deps.length == 1 }}property {{= it.util.escapeQuotes($deps[0]) }}{{??}}properties {{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}} when property {{= it.util.escapeQuotes($property) }} is present'",
enum: "'should be equal to one of values'",
format: "'should match format {{=it.util.escapeQuotes($schema)}}'",
maximum: "'should be {{=$op}} {{=$schema}}'",
minimum: "'should be {{=$op}} {{=$schema}}'",
maxItems: "'should NOT have more than {{=$schema}} items'",
minItems: "'should NOT have less than {{=$schema}} items'",
maxLength: "'should NOT be longer than {{=$schema}} characters'",
minLength: "'should NOT be shorter than {{=$schema}} characters'",
maxProperties: "'should NOT have more than {{=$schema}} properties'",
minProperties: "'should NOT have less than {{=$schema}} properties'",
multipleOf: "'should be multiple of {{=$schema}}'",
not: "'should NOT be valid'",
oneOf: "'should match exactly one schema in oneOf'",
pattern: "'should match pattern \"{{=it.util.escapeQuotes($schema)}}\"'",
required: "'{{? it.opts._errorDataPathProperty }}is a required property{{??}}should have required property \\'{{=$missingProperty}}\\'{{?}}'",
type: "'should be {{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}'",
uniqueItems: "'should NOT have duplicate items (items ## ' + j + ' and ' + i + ' are identical)'",
custom: "'should pass \"{{=$rule.keyword}}\" keyword validation'",
patternGroups: "'should NOT have {{=$moreOrLess}} than {{=$limit}} properties matching pattern \"{{=it.util.escapeQuotes($pgProperty)}}\"'",
switch: "'should pass \"switch\" keyword validation'"
} #}}


{{## def._errorSchemas = {
$ref: "{{=it.util.toQuotedString($schema)}}",
additionalItems: "false",
additionalProperties: "false",
anyOf: "validate.schema{{=$schemaPath}}",
dependencies: "validate.schema{{=$schemaPath}}",
enum: "validate.schema{{=$schemaPath}}",
format: "{{=it.util.toQuotedString($schema)}}",
maximum: "{{=$schema}}",
minimum: "{{=$schema}}",
maxItems: "{{=$schema}}",
minItems: "{{=$schema}}",
maxLength: "{{=$schema}}",
minLength: "{{=$schema}}",
maxProperties: "{{=$schema}}",
minProperties: "{{=$schema}}",
multipleOf: "{{=$schema}}",
not: "validate.schema{{=$schemaPath}}",
oneOf: "validate.schema{{=$schemaPath}}",
pattern: "{{=it.util.toQuotedString($schema)}}",
required: "validate.schema{{=$schemaPath}}",
type: "{{? $isArray }}['{{= $typeSchema.join(\"','\") }}']{{??}}'{{=$typeSchema}}'{{?}}",
uniqueItems: "{{=$schema}}",
custom: "validate.schema{{=$schemaPath}}",
patternGroups: "validate.schema{{=$schemaPath}}",
switch: "validate.schema{{=$schemaPath}}"
} #}}


{{## def._errorParams = {
$ref: "{ ref: '{{=it.util.escapeQuotes($schema)}}' }",
additionalItems: "{ limit: {{=$schema.length}} }",
additionalProperties: "{ additionalProperty: '{{=$additionalProperty}}' }",
anyOf: "{}",
dependencies: "{ property: '{{= it.util.escapeQuotes($property) }}', missingProperty: '{{=$missingProperty}}', depsCount: {{=$deps.length}}, deps: '{{? $deps.length==1 }}{{= it.util.escapeQuotes($deps[0]) }}{{??}}{{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}}' }",
format: "{ format: '{{=it.util.escapeQuotes($schema)}}' }",
maximum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
minimum: "{ comparison: '{{=$op}}', limit: {{=$schema}}, exclusive: {{=$exclusive}} }",
maxItems: "{ limit: {{=$schema}} }",
minItems: "{ limit: {{=$schema}} }",
maxLength: "{ limit: {{=$schema}} }",
minLength: "{ limit: {{=$schema}} }",
maxProperties: "{ limit: {{=$schema}} }",
minProperties: "{ limit: {{=$schema}} }",
multipleOf: "{ multipleOf: {{=$schema}} }",
not: "{}",
oneOf: "{}",
pattern: "{ pattern: '{{=it.util.escapeQuotes($schema)}}' }",
required: "{ missingProperty: '{{=$missingProperty}}' }",
type: "{ type: '{{? $isArray }}{{= $typeSchema.join(\",\") }}{{??}}{{=$typeSchema}}{{?}}' }",
uniqueItems: "{ i: i, j: j }",
custom: "{ keyword: '{{=$rule.keyword}}' }",
patternGroups: "{ reason: '{{=$reason}}', limit: {{=$limit}}, pattern: '{{=it.util.escapeQuotes($pgProperty)}}' }",
switch: "{ caseIndex: {{=$caseIndex}} }"
} #}}
1 change: 1 addition & 0 deletions lib/dot/format.jst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'format' }}

{{
Expand Down
1 change: 1 addition & 0 deletions lib/dot/items.jst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setup:'items' }}
{{# def.setupNextLevel }}

Expand Down

0 comments on commit 16b6ee5

Please sign in to comment.