pax_global_header00006660000000000000000000000064135101753670014522gustar00rootroot0000000000000052 comment=daa7d9159fda5adf94b380a009b8d5ff09a21b10 ajv-keywords-3.4.1/000077500000000000000000000000001351017536700141545ustar00rootroot00000000000000ajv-keywords-3.4.1/.eslintrc.yml000066400000000000000000000014461351017536700166050ustar00rootroot00000000000000env: node: true mocha: true es6: true extends: 'eslint:recommended' globals: Promise: false parserOptions: ecmaVersion: 6 rules: indent-legacy: [ 2, 2, { SwitchCase: 1 } ] no-trailing-spaces: 2 quotes: [ 2, single, avoid-escape ] linebreak-style: [ 2, unix ] semi: [ 2, always ] valid-jsdoc: [ 2, { requireReturn: false } ] no-invalid-this: 2 no-unused-vars: [ 2, { args: none } ] # no-console: [ 2, { allow: [ warn, error ] } ] no-console: 0 block-scoped-var: 2 complexity: [ 2, 18 ] curly: [ 2, multi-or-nest, consistent ] dot-location: [ 2, property ] dot-notation: 2 no-else-return: 2 no-eq-null: 2 no-fallthrough: 2 no-return-assign: 2 strict: [ 2, global ] no-shadow: 1 no-use-before-define: [ 2, nofunc ] callback-return: 2 no-path-concat: 2 ajv-keywords-3.4.1/.gitignore000066400000000000000000000011551351017536700161460ustar00rootroot00000000000000 package-lock.json # Logs logs *.log npm-debug.log* # Runtime data pids *.pid *.seed # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directory node_modules # Optional npm cache directory .npm # Optional REPL history .node_repl_history # Compiled templates keywords/dotjs/*.js .DS_Store # IDE .idea *.iml ajv-keywords-3.4.1/.travis.yml000066400000000000000000000001571351017536700162700ustar00rootroot00000000000000language: node_js node_js: - "8" - "10" - "11" - "12" after_script: - coveralls < coverage/lcov.info ajv-keywords-3.4.1/LICENSE000066400000000000000000000020741351017536700151640ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2016 Evgeny Poberezkin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ajv-keywords-3.4.1/README.md000066400000000000000000000615731351017536700154470ustar00rootroot00000000000000# ajv-keywords Custom JSON-Schema keywords for [Ajv](https://github.com/epoberezkin/ajv) validator [![Build Status](https://travis-ci.org/epoberezkin/ajv-keywords.svg?branch=master)](https://travis-ci.org/epoberezkin/ajv-keywords) [![npm](https://img.shields.io/npm/v/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords) [![npm downloads](https://img.shields.io/npm/dm/ajv-keywords.svg)](https://www.npmjs.com/package/ajv-keywords) [![Coverage Status](https://coveralls.io/repos/github/epoberezkin/ajv-keywords/badge.svg?branch=master)](https://coveralls.io/github/epoberezkin/ajv-keywords?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/epoberezkin/ajv-keywords.svg)](https://greenkeeper.io/) [![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv) ## Contents - [Install](#install) - [Usage](#usage) - [Keywords](#keywords) - [Types](#types) - [typeof](#typeof) - [instanceof](#instanceof) - [Keywords for numbers](#keywords-for-numbers) - [range and exclusiveRange](#range-and-exclusiverange) - [Keywords for strings](#keywords-for-strings) - [regexp](#regexp) - [formatMaximum / formatMinimum and formatExclusiveMaximum / formatExclusiveMinimum](#formatmaximum--formatminimum-and-formatexclusivemaximum--formatexclusiveminimum) - [transform](#transform)\* - [Keywords for arrays](#keywords-for-arrays) - [uniqueItemProperties](#uniqueitemproperties) - [Keywords for objects](#keywords-for-objects) - [allRequired](#allrequired) - [anyRequired](#anyrequired) - [oneRequired](#onerequired) - [patternRequired](#patternrequired) - [prohibited](#prohibited) - [deepProperties](#deepproperties) - [deepRequired](#deeprequired) - [Compound keywords](#compound-keywords) - [switch](#switch) (deprecated) - [select/selectCases/selectDefault](#selectselectcasesselectdefault) (BETA) - [Keywords for all types](#keywords-for-all-types) - [dynamicDefaults](#dynamicdefaults)\* - [License](#license) \* - keywords that modify data ## Install ``` npm install ajv-keywords ``` ## Usage To add all available keywords: ```javascript var Ajv = require('ajv'); var ajv = new Ajv; require('ajv-keywords')(ajv); ajv.validate({ instanceof: 'RegExp' }, /.*/); // true ajv.validate({ instanceof: 'RegExp' }, '.*'); // false ``` To add a single keyword: ```javascript require('ajv-keywords')(ajv, 'instanceof'); ``` To add multiple keywords: ```javascript require('ajv-keywords')(ajv, ['typeof', 'instanceof']); ``` To add a single keyword in browser (to avoid adding unused code): ```javascript require('ajv-keywords/keywords/instanceof')(ajv); ``` ## Keywords ### Types #### `typeof` Based on JavaScript `typeof` operation. The value of the keyword should be a string (`"undefined"`, `"string"`, `"number"`, `"object"`, `"function"`, `"boolean"` or `"symbol"`) or array of strings. To pass validation the result of `typeof` operation on the value should be equal to the string (or one of the strings in the array). ``` ajv.validate({ typeof: 'undefined' }, undefined); // true ajv.validate({ typeof: 'undefined' }, null); // false ajv.validate({ typeof: ['undefined', 'object'] }, null); // true ``` #### `instanceof` Based on JavaScript `instanceof` operation. The value of the keyword should be a string (`"Object"`, `"Array"`, `"Function"`, `"Number"`, `"String"`, `"Date"`, `"RegExp"`, `"Promise"` or `"Buffer"`) or array of strings. To pass validation the result of `data instanceof ...` operation on the value should be true: ``` ajv.validate({ instanceof: 'Array' }, []); // true ajv.validate({ instanceof: 'Array' }, {}); // false ajv.validate({ instanceof: ['Array', 'Function'] }, function(){}); // true ``` You can add your own constructor function to be recognised by this keyword: ```javascript function MyClass() {} var instanceofDefinition = require('ajv-keywords').get('instanceof').definition; // or require('ajv-keywords/keywords/instanceof').definition; instanceofDefinition.CONSTRUCTORS.MyClass = MyClass; ajv.validate({ instanceof: 'MyClass' }, new MyClass); // true ``` ### Keywords for numbers #### `range` and `exclusiveRange` Syntax sugar for the combination of minimum and maximum keywords, also fails schema compilation if there are no numbers in the range. The value of this keyword must be the array consisting of two numbers, the second must be greater or equal than the first one. If the validated value is not a number the validation passes, otherwise to pass validation the value should be greater (or equal) than the first number and smaller (or equal) than the second number in the array. If `exclusiveRange` keyword is present in the same schema and its value is true, the validated value must not be equal to the range boundaries. ```javascript var schema = { range: [1, 3] }; ajv.validate(schema, 1); // true ajv.validate(schema, 2); // true ajv.validate(schema, 3); // true ajv.validate(schema, 0.99); // false ajv.validate(schema, 3.01); // false var schema = { range: [1, 3], exclusiveRange: true }; ajv.validate(schema, 1.01); // true ajv.validate(schema, 2); // true ajv.validate(schema, 2.99); // true ajv.validate(schema, 1); // false ajv.validate(schema, 3); // false ``` ### Keywords for strings #### `regexp` This keyword allows to use regular expressions with flags in schemas (the standard `pattern` keyword does not support flags). This keyword applies only to strings. If the data is not a string, the validation succeeds. The value of this keyword can be either a string (the result of `regexp.toString()`) or an object with the properties `pattern` and `flags` (the same strings that should be passed to RegExp constructor). ```javascript var schema = { type: 'object', properties: { foo: { regexp: '/foo/i' }, bar: { regexp: { pattern: 'bar', flags: 'i' } } } }; var validData = { foo: 'Food', bar: 'Barmen' }; var invalidData = { foo: 'fog', bar: 'bad' }; ``` #### `formatMaximum` / `formatMinimum` and `formatExclusiveMaximum` / `formatExclusiveMinimum` These keywords allow to define minimum/maximum constraints when the format keyword defines ordering. These keywords apply only to strings. If the data is not a string, the validation succeeds. The value of keyword `formatMaximum` (`formatMinimum`) should be a string. This value is the maximum (minimum) allowed value for the data to be valid as determined by `format` keyword. If `format` is not present schema compilation will throw exception. When this keyword is added, it defines comparison rules for formats `"date"`, `"time"` and `"date-time"`. Custom formats also can have comparison rules. See [addFormat](https://github.com/epoberezkin/ajv#api-addformat) method. The value of keyword `formatExclusiveMaximum` (`formatExclusiveMinimum`) should be a boolean value. These keyword cannot be used without `formatMaximum` (`formatMinimum`). If this keyword value is equal to `true`, the data to be valid should not be equal to the value in `formatMaximum` (`formatMinimum`) keyword. ```javascript require('ajv-keywords')(ajv, ['formatMinimum', 'formatMaximum']); var schema = { format: 'date', formatMinimum: '2016-02-06', formatMaximum: '2016-12-27', formatExclusiveMaximum: true } var validDataList = ['2016-02-06', '2016-12-26', 1]; var invalidDataList = ['2016-02-05', '2016-12-27', 'abc']; ``` #### `transform` This keyword allows a string to be modified before validation. These keywords apply only to strings. If the data is not a string, the transform is skipped. There are limitation due to how ajv is written: - a stand alone string cannot be transformed. ie `data = 'a'; ajv.validate(schema, data);` - currently cannot work with `ajv-pack` **Supported options:** - `trim`: remove whitespace from start and end - `trimLeft`: remove whitespace from start - `trimRight`: remove whitespace from end - `toLowerCase`: case string to all lower case - `toUpperCase`: case string to all upper case - `toEnumCase`: case string to match case in schema Options are applied in the order they are listed. Note: `toEnumCase` requires that all allowed values are unique when case insensitive. **Example: multiple options** ```javascript require('ajv-keywords')(ajv, ['transform']); var schema = { type: 'array', items: { type:'string', transform:['trim','toLowerCase'] } }; var data = [' MixCase ']; ajv.validate(schema, data); console.log(data); // ['mixcase'] ``` **Example: `enumcase`** ```javascript require('ajv-keywords')(ajv, ['transform']); var schema = { type: 'array', items: { type:'string', transform:['trim','toEnumCase'], enum:['pH'] } }; var data = ['ph',' Ph','PH','pH ']; ajv.validate(schema, data); console.log(data); // ['pH','pH','pH','pH'] ``` ### Keywords for arrays #### `uniqueItemProperties` The keyword allows to check that some properties in array items are unique. This keyword applies only to arrays. If the data is not an array, the validation succeeds. The value of this keyword must be an array of strings - property names that should have unique values across all items. ```javascript var schema = { uniqueItemProperties: [ "id", "name" ] }; var validData = [ { id: 1 }, { id: 2 }, { id: 3 } ]; var invalidData1 = [ { id: 1 }, { id: 1 }, // duplicate "id" { id: 3 } ]; var invalidData2 = [ { id: 1, name: "taco" }, { id: 2, name: "taco" }, // duplicate "name" { id: 3, name: "salsa" } ]; ``` This keyword is contributed by [@blainesch](https://github.com/blainesch). ### Keywords for objects #### `allRequired` This keyword allows to require the presence of all properties used in `properties` keyword in the same schema object. This keyword applies only to objects. If the data is not an object, the validation succeeds. The value of this keyword must be boolean. If the value of the keyword is `false`, the validation succeeds. If the value of the keyword is `true`, the validation succeeds if the data contains all properties defined in `properties` keyword (in the same schema object). If the `properties` keyword is not present in the same schema object, schema compilation will throw exception. ```javascript var schema = { properties: { foo: {type: 'number'}, bar: {type: 'number'} } allRequired: true }; var validData = { foo: 1, bar: 2 }; var alsoValidData = { foo: 1, bar: 2, baz: 3 }; var invalidDataList = [ {}, { foo: 1 }, { bar: 2 } ]; ``` #### `anyRequired` This keyword allows to require the presence of any (at least one) property from the list. This keyword applies only to objects. If the data is not an object, the validation succeeds. The value of this keyword must be an array of strings, each string being a property name. For data object to be valid at least one of the properties in this array should be present in the object. ```javascript var schema = { anyRequired: ['foo', 'bar'] }; var validData = { foo: 1 }; var alsoValidData = { foo: 1, bar: 2 }; var invalidDataList = [ {}, { baz: 3 } ]; ``` #### `oneRequired` This keyword allows to require the presence of only one property from the list. This keyword applies only to objects. If the data is not an object, the validation succeeds. The value of this keyword must be an array of strings, each string being a property name. For data object to be valid exactly one of the properties in this array should be present in the object. ```javascript var schema = { oneRequired: ['foo', 'bar'] }; var validData = { foo: 1 }; var alsoValidData = { bar: 2, baz: 3 }; var invalidDataList = [ {}, { baz: 3 }, { foo: 1, bar: 2 } ]; ``` #### `patternRequired` This keyword allows to require the presence of properties that match some pattern(s). This keyword applies only to objects. If the data is not an object, the validation succeeds. The value of this keyword should be an array of strings, each string being a regular expression. For data object to be valid each regular expression in this array should match at least one property name in the data object. If the array contains multiple regular expressions, more than one expression can match the same property name. ```javascript var schema = { patternRequired: [ 'f.*o', 'b.*r' ] }; var validData = { foo: 1, bar: 2 }; var alsoValidData = { foobar: 3 }; var invalidDataList = [ {}, { foo: 1 }, { bar: 2 } ]; ``` #### `prohibited` This keyword allows to prohibit that any of the properties in the list is present in the object. This keyword applies only to objects. If the data is not an object, the validation succeeds. The value of this keyword should be an array of strings, each string being a property name. For data object to be valid none of the properties in this array should be present in the object. ``` var schema = { prohibited: ['foo', 'bar']}; var validData = { baz: 1 }; var alsoValidData = {}; var invalidDataList = [ { foo: 1 }, { bar: 2 }, { foo: 1, bar: 2} ]; ``` __Please note__: `{prohibited: ['foo', 'bar']}` is equivalent to `{not: {anyRequired: ['foo', 'bar']}}` (i.e. it has the same validation result for any data). #### `deepProperties` This keyword allows to validate deep properties (identified by JSON pointers). This keyword applies only to objects. If the data is not an object, the validation succeeds. The value should be an object, where keys are JSON pointers to the data, starting from the current position in data, and the values are JSON schemas. For data object to be valid the value of each JSON pointer should be valid according to the corresponding schema. ```javascript var schema = { type: 'object', deepProperties: { "/users/1/role": { "enum": ["admin"] } } }; var validData = { users: [ {}, { id: 123, role: 'admin' } ] }; var alsoValidData = { users: { "1": { id: 123, role: 'admin' } } }; var invalidData = { users: [ {}, { id: 123, role: 'user' } ] }; var alsoInvalidData = { users: { "1": { id: 123, role: 'user' } } }; ``` #### `deepRequired` This keyword allows to check that some deep properties (identified by JSON pointers) are available. This keyword applies only to objects. If the data is not an object, the validation succeeds. The value should be an array of JSON pointers to the data, starting from the current position in data. For data object to be valid each JSON pointer should be some existing part of the data. ```javascript var schema = { type: 'object', deepRequired: ["/users/1/role"] }; var validData = { users: [ {}, { id: 123, role: 'admin' } ] }; var invalidData = { users: [ {}, { id: 123 } ] }; ``` See [json-schema-org/json-schema-spec#203](https://github.com/json-schema-org/json-schema-spec/issues/203#issue-197211916) for an example of the equivalent schema without `deepRequired` keyword. ### Compound keywords #### `switch` (deprecated) __Please note__: this keyword is provided to preserve backward compatibility with previous versions of Ajv. It is strongly recommended to use `if`/`then`/`else` keywords instead, as they have been added to the draft-07 of JSON Schema specification. This keyword allows to perform advanced conditional validation. The value of the keyword is the array of if/then clauses. Each clause is the object with the following properties: - `if` (optional) - the value is JSON-schema - `then` (required) - the value is JSON-schema or boolean - `continue` (optional) - the value is boolean The validation process is dynamic; all clauses are executed sequentially in the following way: 1. `if`: 1. `if` property is JSON-schema according to which the data is: 1. valid => go to step 2. 2. invalid => go to the NEXT clause, if this was the last clause the validation of `switch` SUCCEEDS. 2. `if` property is absent => go to step 2. 2. `then`: 1. `then` property is `true` or it is JSON-schema according to which the data is valid => go to step 3. 2. `then` property is `false` or it is JSON-schema according to which the data is invalid => the validation of `switch` FAILS. 3. `continue`: 1. `continue` property is `true` => go to the NEXT clause, if this was the last clause the validation of `switch` SUCCEEDS. 2. `continue` property is `false` or absent => validation of `switch` SUCCEEDS. ```javascript require('ajv-keywords')(ajv, 'switch'); var schema = { type: 'array', items: { type: 'integer', 'switch': [ { if: { not: { minimum: 1 } }, then: false }, { if: { maximum: 10 }, then: true }, { if: { maximum: 100 }, then: { multipleOf: 10 } }, { if: { maximum: 1000 }, then: { multipleOf: 100 } }, { then: false } ] } }; var validItems = [1, 5, 10, 20, 50, 100, 200, 500, 1000]; var invalidItems = [1, 0, 2000, 11, 57, 123, 'foo']; ``` The above schema is equivalent to (for example): ```javascript { type: 'array', items: { type: 'integer', if: { minimum: 1, maximum: 10 }, then: true, else: { if: { maximum: 100 }, then: { multipleOf: 10 }, else: { if: { maximum: 1000 }, then: { multipleOf: 100 }, else: false } } } } ``` #### `select`/`selectCases`/`selectDefault` These keywords allow to choose the schema to validate the data based on the value of some property in the validated data. These keywords must be present in the same schema object (`selectDefault` is optional). The value of `select` keyword should be a [$data reference](https://github.com/epoberezkin/ajv/tree/5.0.2-beta.0#data-reference) that points to any primitive JSON type (string, number, boolean or null) in the data that is validated. You can also use a constant of primitive type as the value of this keyword (e.g., for debugging purposes). The value of `selectCases` keyword must be an object where each property name is a possible string representation of the value of `select` keyword and each property value is a corresponding schema (from draft-06 it can be boolean) that must be used to validate the data. The value of `selectDefault` keyword is a schema (from draft-06 it can be boolean) that must be used to validate the data in case `selectCases` has no key equal to the stringified value of `select` keyword. The validation succeeds in one of the following cases: - the validation of data using selected schema succeeds, - none of the schemas is selected for validation, - the value of select is undefined (no property in the data that the data reference points to). If `select` value (in data) is not a primitive type the validation fails. __Please note__: these keywords require Ajv `$data` option to support [$data reference](https://github.com/epoberezkin/ajv/tree/5.0.2-beta.0#data-reference). ```javascript require('ajv-keywords')(ajv, 'select'); var schema = { type: object, required: ['kind'], properties: { kind: { type: 'string' } }, select: { $data: '0/kind' }, selectCases: { foo: { required: ['foo'], properties: { kind: {}, foo: { type: 'string' } }, additionalProperties: false }, bar: { required: ['bar'], properties: { kind: {}, bar: { type: 'number' } }, additionalProperties: false } }, selectDefault: { propertyNames: { not: { enum: ['foo', 'bar'] } } } }; var validDataList = [ { kind: 'foo', foo: 'any' }, { kind: 'bar', bar: 1 }, { kind: 'anything_else', not_bar_or_foo: 'any value' } ]; var invalidDataList = [ { kind: 'foo' }, // no propery foo { kind: 'bar' }, // no propery bar { kind: 'foo', foo: 'any', another: 'any value' }, // additional property { kind: 'bar', bar: 1, another: 'any value' }, // additional property { kind: 'anything_else', foo: 'any' } // property foo not allowed { kind: 'anything_else', bar: 1 } // property bar not allowed ]; ``` __Please note__: the current implementation is BETA. It does not allow using relative URIs in $ref keywords in schemas in `selectCases` and `selectDefault` that point outside of these schemas. The workaround is to use absolute URIs (that can point to any (sub-)schema added to Ajv, including those inside the current root schema where `select` is used). See [tests](https://github.com/epoberezkin/ajv-keywords/blob/v2.0.0/spec/tests/select.json#L314). ### Keywords for all types #### `dynamicDefaults` This keyword allows to assign dynamic defaults to properties, such as timestamps, unique IDs etc. This keyword only works if `useDefaults` options is used and not inside `anyOf` keywords etc., in the same way as [default keyword treated by Ajv](https://github.com/epoberezkin/ajv#assigning-defaults). The keyword should be added on the object level. Its value should be an object with each property corresponding to a property name, in the same way as in standard `properties` keyword. The value of each property can be: - an identifier of default function (a string) - an object with properties `func` (an identifier) and `args` (an object with parameters that will be passed to this function during schema compilation - see examples). The properties used in `dynamicDefaults` should not be added to `required` keyword (or validation will fail), because unlike `default` this keyword is processed after validation. There are several predefined dynamic default functions: - `"timestamp"` - current timestamp in milliseconds - `"datetime"` - current date and time as string (ISO, valid according to `date-time` format) - `"date"` - current date as string (ISO, valid according to `date` format) - `"time"` - current time as string (ISO, valid according to `time` format) - `"random"` - pseudo-random number in [0, 1) interval - `"randomint"` - pseudo-random integer number. If string is used as a property value, the function will randomly return 0 or 1. If object `{ func: 'randomint', args: { max: N } }` is used then the default will be an integer number in [0, N) interval. - `"seq"` - sequential integer number starting from 0. If string is used as a property value, the default sequence will be used. If object `{ func: 'seq', args: { name: 'foo'} }` is used then the sequence with name `"foo"` will be used. Sequences are global, even if different ajv instances are used. ```javascript var schema = { type: 'object', dynamicDefaults: { ts: 'datetime', r: { func: 'randomint', args: { max: 100 } }, id: { func: 'seq', args: { name: 'id' } } }, properties: { ts: { type: 'string', format: 'date-time' }, r: { type: 'integer', minimum: 0, exclusiveMaximum: 100 }, id: { type: 'integer', minimum: 0 } } }; var data = {}; ajv.validate(data); // true data; // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 } var data1 = {}; ajv.validate(data1); // true data1; // { ts: '2016-12-01T22:07:29.832Z', r: 68, id: 1 } ajv.validate(data1); // true data1; // didn't change, as all properties were defined ``` When using the `useDefaults` option value `"empty"`, properties and items equal to `null` or `""` (empty string) will be considered missing and assigned defaults. Use the `allOf` [compound keyword](https://github.com/epoberezkin/ajv/blob/master/KEYWORDS.md#compound-keywords) to execute `dynamicDefaults` before validation. ```javascript var schema = { allOf: [ { dynamicDefaults: { ts: 'datetime', r: { func: 'randomint', args: { min: 5, max: 100 } }, id: { func: 'seq', args: { name: 'id' } } } }, { type: 'object', properties: { ts: { type: 'string' }, r: { type: 'number', minimum: 5, exclusiveMaximum: 100 }, id: { type: 'integer', minimum: 0 } } } ] }; var data = { ts: '', r: null }; ajv.validate(data); // true data; // { ts: '2016-12-01T22:07:28.829Z', r: 25, id: 0 } ``` You can add your own dynamic default function to be recognised by this keyword: ```javascript var uuid = require('uuid'); function uuidV4() { return uuid.v4(); } var definition = require('ajv-keywords').get('dynamicDefaults').definition; // or require('ajv-keywords/keywords/dynamicDefaults').definition; definition.DEFAULTS.uuid = uuidV4; var schema = { dynamicDefaults: { id: 'uuid' }, properties: { id: { type: 'string', format: 'uuid' } } }; var data = {}; ajv.validate(schema, data); // true data; // { id: 'a1183fbe-697b-4030-9bcc-cfeb282a9150' }; var data1 = {}; ajv.validate(schema, data1); // true data1; // { id: '5b008de7-1669-467a-a5c6-70fa244d7209' } ``` You also can define dynamic default that accepts parameters, e.g. version of uuid: ```javascript var uuid = require('uuid'); function getUuid(args) { var version = 'v' + (arvs && args.v || 4); return function() { return uuid[version](); }; } var definition = require('ajv-keywords').get('dynamicDefaults').definition; definition.DEFAULTS.uuid = getUuid; var schema = { dynamicDefaults: { id1: 'uuid', // v4 id2: { func: 'uuid', v: 4 }, // v4 id3: { func: 'uuid', v: 1 } // v1 } }; ``` ## License [MIT](https://github.com/epoberezkin/ajv-keywords/blob/master/LICENSE) ajv-keywords-3.4.1/index.js000066400000000000000000000013711351017536700156230ustar00rootroot00000000000000'use strict'; var KEYWORDS = require('./keywords'); module.exports = defineKeywords; /** * Defines one or several keywords in ajv instance * @param {Ajv} ajv validator instance * @param {String|Array|undefined} keyword keyword(s) to define * @return {Ajv} ajv instance (for chaining) */ function defineKeywords(ajv, keyword) { if (Array.isArray(keyword)) { for (var i=0; i d2) return 1; if (d1 < d2) return -1; if (d1 === d2) return 0; } function compareTime(t1, t2) { if (!(t1 && t2)) return; t1 = t1.match(TIME); t2 = t2.match(TIME); if (!(t1 && t2)) return; t1 = t1[1] + t1[2] + t1[3] + (t1[4]||''); t2 = t2[1] + t2[2] + t2[3] + (t2[4]||''); if (t1 > t2) return 1; if (t1 < t2) return -1; if (t1 === t2) return 0; } function compareDateTime(dt1, dt2) { if (!(dt1 && dt2)) return; dt1 = dt1.split(DATE_TIME_SEPARATOR); dt2 = dt2.split(DATE_TIME_SEPARATOR); var res = compareDate(dt1[0], dt2[0]); if (res === undefined) return; return res || compareTime(dt1[1], dt2[1]); } ajv-keywords-3.4.1/keywords/_util.js000066400000000000000000000006221351017536700174750ustar00rootroot00000000000000'use strict'; module.exports = { metaSchemaRef: metaSchemaRef }; var META_SCHEMA_ID = 'http://json-schema.org/draft-07/schema'; function metaSchemaRef(ajv) { var defaultMeta = ajv._opts.defaultMeta; if (typeof defaultMeta == 'string') return { $ref: defaultMeta }; if (ajv.getSchema(META_SCHEMA_ID)) return { $ref: META_SCHEMA_ID }; console.warn('meta schema not defined'); return {}; } ajv-keywords-3.4.1/keywords/allRequired.js000066400000000000000000000007321351017536700206340ustar00rootroot00000000000000'use strict'; module.exports = function defFunc(ajv) { defFunc.definition = { type: 'object', macro: function (schema, parentSchema) { if (!schema) return true; var properties = Object.keys(parentSchema.properties); if (properties.length == 0) return true; return {required: properties}; }, metaSchema: {type: 'boolean'}, dependencies: ['properties'] }; ajv.addKeyword('allRequired', defFunc.definition); return ajv; }; ajv-keywords-3.4.1/keywords/anyRequired.js000066400000000000000000000010231351017536700206450ustar00rootroot00000000000000'use strict'; module.exports = function defFunc(ajv) { defFunc.definition = { type: 'object', macro: function (schema) { if (schema.length == 0) return true; if (schema.length == 1) return {required: schema}; var schemas = schema.map(function (prop) { return {required: [prop]}; }); return {anyOf: schemas}; }, metaSchema: { type: 'array', items: { type: 'string' } } }; ajv.addKeyword('anyRequired', defFunc.definition); return ajv; }; ajv-keywords-3.4.1/keywords/deepProperties.js000066400000000000000000000025161351017536700213570ustar00rootroot00000000000000'use strict'; var util = require('./_util'); module.exports = function defFunc(ajv) { defFunc.definition = { type: 'object', macro: function (schema) { var schemas = []; for (var pointer in schema) schemas.push(getSchema(pointer, schema[pointer])); return {'allOf': schemas}; }, metaSchema: { type: 'object', propertyNames: { type: 'string', format: 'json-pointer' }, additionalProperties: util.metaSchemaRef(ajv) } }; ajv.addKeyword('deepProperties', defFunc.definition); return ajv; }; function getSchema(jsonPointer, schema) { var segments = jsonPointer.split('/'); var rootSchema = {}; var pointerSchema = rootSchema; for (var i=1; i' , $result = 'result' + $lvl; }} {{# def.$data }} {{? $isDataExcl }} {{ var $schemaValueExcl = it.util.getData($schemaExcl.$data, $dataLvl, it.dataPathArr) , $exclusive = 'exclusive' + $lvl , $opExpr = 'op' + $lvl , $opStr = '\' + ' + $opExpr + ' + \''; }} var schemaExcl{{=$lvl}} = {{=$schemaValueExcl}}; {{ $schemaValueExcl = 'schemaExcl' + $lvl; }} if (typeof {{=$schemaValueExcl}} != 'boolean' && {{=$schemaValueExcl}} !== undefined) { {{=$valid}} = false; {{ var $errorKeyword = $exclusiveKeyword; }} {{# def.error:'_formatExclusiveLimit' }} } {{# def.elseIfValid }} {{# def.compareFormat }} var {{=$exclusive}} = {{=$schemaValueExcl}} === true; if ({{=$valid}} === undefined) { {{=$valid}} = {{=$exclusive}} ? {{=$result}} {{=$op}} 0 : {{=$result}} {{=$op}}= 0; } if (!{{=$valid}}) var op{{=$lvl}} = {{=$exclusive}} ? '{{=$op}}' : '{{=$op}}='; {{??}} {{ var $exclusive = $schemaExcl === true , $opStr = $op; /*used in error*/ if (!$exclusive) $opStr += '='; var $opExpr = '\'' + $opStr + '\''; /*used in error*/ }} {{# def.compareFormat }} if ({{=$valid}} === undefined) {{=$valid}} = {{=$result}} {{=$op}}{{?!$exclusive}}={{?}} 0; {{?}} {{= $closingBraces }} if (!{{=$valid}}) { {{ var $errorKeyword = $keyword; }} {{# def.error:'_formatLimit' }} } ajv-keywords-3.4.1/keywords/dot/patternRequired.jst000066400000000000000000000014151351017536700225120ustar00rootroot00000000000000{{# def.definitions }} {{# def.errors }} {{# def.setupKeyword }} {{ var $key = 'key' + $lvl , $idx = 'idx' + $lvl , $matched = 'patternMatched' + $lvl , $dataProperties = 'dataProperties' + $lvl , $closingBraces = '' , $ownProperties = it.opts.ownProperties; }} var {{=$valid}} = true; {{? $ownProperties }} var {{=$dataProperties}} = undefined; {{?}} {{~ $schema:$pProperty }} var {{=$matched}} = false; {{# def.iterateProperties }} {{=$matched}} = {{= it.usePattern($pProperty) }}.test({{=$key}}); if ({{=$matched}}) break; } {{ var $missingPattern = it.util.escapeQuotes($pProperty); }} if (!{{=$matched}}) { {{=$valid}} = false; {{# def.addError:'patternRequired' }} } {{# def.elseIfValid }} {{~}} {{= $closingBraces }} ajv-keywords-3.4.1/keywords/dot/switch.jst000066400000000000000000000030071351017536700206340ustar00rootroot00000000000000{{# def.definitions }} {{# def.errors }} {{# def.setupKeyword }} {{# def.setupNextLevel }} {{## def.validateIf: {{# def.setCompositeRule }} {{ $it.createErrors = false; }} {{# def._validateSwitchRule:if }} {{ $it.createErrors = true; }} {{# def.resetCompositeRule }} {{=$ifPassed}} = {{=$nextValid}}; #}} {{## def.validateThen: {{? typeof $sch.then == 'boolean' }} {{? $sch.then === false }} {{# def.error:'switch' }} {{?}} var {{=$nextValid}} = {{= $sch.then }}; {{??}} {{# def._validateSwitchRule:then }} {{?}} #}} {{## def._validateSwitchRule:_clause: {{ $it.schema = $sch._clause; $it.schemaPath = $schemaPath + '[' + $caseIndex + ']._clause'; $it.errSchemaPath = $errSchemaPath + '/' + $caseIndex + '/_clause'; }} {{# def.insertSubschemaCode }} #}} {{## def.switchCase: {{? $sch.if && {{# def.nonEmptySchema:$sch.if }} }} var {{=$errs}} = errors; {{# def.validateIf }} if ({{=$ifPassed}}) { {{# def.validateThen }} } else { {{# def.resetErrors }} } {{??}} {{=$ifPassed}} = true; {{# def.validateThen }} {{?}} #}} {{ var $ifPassed = 'ifPassed' + it.level , $currentBaseId = $it.baseId , $shouldContinue; }} var {{=$ifPassed}}; {{~ $schema:$sch:$caseIndex }} {{? $caseIndex && !$shouldContinue }} if (!{{=$ifPassed}}) { {{ $closingBraces+= '}'; }} {{?}} {{# def.switchCase }} {{ $shouldContinue = $sch.continue }} {{~}} {{= $closingBraces }} var {{=$valid}} = {{=$nextValid}}; {{# def.cleanUp }} ajv-keywords-3.4.1/keywords/dotjs/000077500000000000000000000000001351017536700171465ustar00rootroot00000000000000ajv-keywords-3.4.1/keywords/dotjs/README.md000066400000000000000000000002361351017536700204260ustar00rootroot00000000000000These files are compiled dot templates from dot folder. Do NOT edit them directly, edit the templates and run `npm run build` from main ajv-keywords folder. ajv-keywords-3.4.1/keywords/dynamicDefaults.js000066400000000000000000000037301351017536700215000ustar00rootroot00000000000000'use strict'; var sequences = {}; var DEFAULTS = { timestamp: function() { return Date.now(); }, datetime: function() { return (new Date).toISOString(); }, date: function() { return (new Date).toISOString().slice(0, 10); }, time: function() { return (new Date).toISOString().slice(11); }, random: function() { return Math.random(); }, randomint: function (args) { var limit = args && args.max || 2; return function() { return Math.floor(Math.random() * limit); }; }, seq: function (args) { var name = args && args.name || ''; sequences[name] = sequences[name] || 0; return function() { return sequences[name]++; }; } }; module.exports = function defFunc(ajv) { defFunc.definition = { compile: function (schema, parentSchema, it) { var funcs = {}; for (var key in schema) { var d = schema[key]; var func = getDefault(typeof d == 'string' ? d : d.func); funcs[key] = func.length ? func(d.args) : func; } return it.opts.useDefaults && !it.compositeRule ? assignDefaults : noop; function assignDefaults(data) { for (var prop in schema){ if (data[prop] === undefined || (it.opts.useDefaults == 'empty' && (data[prop] === null || data[prop] === ''))) data[prop] = funcs[prop](); } return true; } function noop() { return true; } }, DEFAULTS: DEFAULTS, metaSchema: { type: 'object', additionalProperties: { type: ['string', 'object'], additionalProperties: false, required: ['func', 'args'], properties: { func: { type: 'string' }, args: { type: 'object' } } } } }; ajv.addKeyword('dynamicDefaults', defFunc.definition); return ajv; function getDefault(d) { var def = DEFAULTS[d]; if (def) return def; throw new Error('invalid "dynamicDefaults" keyword property value: ' + d); } }; ajv-keywords-3.4.1/keywords/formatMaximum.js000066400000000000000000000001061351017536700212040ustar00rootroot00000000000000'use strict'; module.exports = require('./_formatLimit')('Maximum'); ajv-keywords-3.4.1/keywords/formatMinimum.js000066400000000000000000000001061351017536700212020ustar00rootroot00000000000000'use strict'; module.exports = require('./_formatLimit')('Minimum'); ajv-keywords-3.4.1/keywords/index.js000066400000000000000000000014021351017536700174650ustar00rootroot00000000000000'use strict'; module.exports = { 'instanceof': require('./instanceof'), range: require('./range'), regexp: require('./regexp'), 'typeof': require('./typeof'), dynamicDefaults: require('./dynamicDefaults'), allRequired: require('./allRequired'), anyRequired: require('./anyRequired'), oneRequired: require('./oneRequired'), prohibited: require('./prohibited'), uniqueItemProperties: require('./uniqueItemProperties'), deepProperties: require('./deepProperties'), deepRequired: require('./deepRequired'), formatMinimum: require('./formatMinimum'), formatMaximum: require('./formatMaximum'), patternRequired: require('./patternRequired'), 'switch': require('./switch'), select: require('./select'), transform: require('./transform') }; ajv-keywords-3.4.1/keywords/instanceof.js000066400000000000000000000024601351017536700205140ustar00rootroot00000000000000'use strict'; var CONSTRUCTORS = { Object: Object, Array: Array, Function: Function, Number: Number, String: String, Date: Date, RegExp: RegExp }; module.exports = function defFunc(ajv) { /* istanbul ignore else */ if (typeof Buffer != 'undefined') CONSTRUCTORS.Buffer = Buffer; /* istanbul ignore else */ if (typeof Promise != 'undefined') CONSTRUCTORS.Promise = Promise; defFunc.definition = { compile: function (schema) { if (typeof schema == 'string') { var Constructor = getConstructor(schema); return function (data) { return data instanceof Constructor; }; } var constructors = schema.map(getConstructor); return function (data) { for (var i=0; i max || (exclusive && min == max)) throw new Error('There are no numbers in range'); } }; ajv-keywords-3.4.1/keywords/regexp.js000066400000000000000000000016771351017536700176660ustar00rootroot00000000000000'use strict'; module.exports = function defFunc(ajv) { defFunc.definition = { type: 'string', inline: function (it, keyword, schema) { return getRegExp() + '.test(data' + (it.dataLevel || '') + ')'; function getRegExp() { try { if (typeof schema == 'object') return new RegExp(schema.pattern, schema.flags); var rx = schema.match(/^\/(.*)\/([gimuy]*)$/); if (rx) return new RegExp(rx[1], rx[2]); throw new Error('cannot parse string into RegExp'); } catch(e) { console.error('regular expression', schema, 'is invalid'); throw e; } } }, metaSchema: { type: ['string', 'object'], properties: { pattern: { type: 'string' }, flags: { type: 'string' } }, required: ['pattern'], additionalProperties: false } }; ajv.addKeyword('regexp', defFunc.definition); return ajv; }; ajv-keywords-3.4.1/keywords/select.js000066400000000000000000000042471351017536700176470ustar00rootroot00000000000000'use strict'; var util = require('./_util'); module.exports = function defFunc(ajv) { if (!ajv._opts.$data) { console.warn('keyword select requires $data option'); return ajv; } var metaSchemaRef = util.metaSchemaRef(ajv); var compiledCaseSchemas = []; defFunc.definition = { validate: function v(schema, data, parentSchema) { if (parentSchema.selectCases === undefined) throw new Error('keyword "selectCases" is absent'); var compiled = getCompiledSchemas(parentSchema, false); var validate = compiled.cases[schema]; if (validate === undefined) validate = compiled.default; if (typeof validate == 'boolean') return validate; var valid = validate(data); if (!valid) v.errors = validate.errors; return valid; }, $data: true, metaSchema: { type: ['string', 'number', 'boolean', 'null'] } }; ajv.addKeyword('select', defFunc.definition); ajv.addKeyword('selectCases', { compile: function (schemas, parentSchema) { var compiled = getCompiledSchemas(parentSchema); for (var value in schemas) compiled.cases[value] = compileOrBoolean(schemas[value]); return function() { return true; }; }, valid: true, metaSchema: { type: 'object', additionalProperties: metaSchemaRef } }); ajv.addKeyword('selectDefault', { compile: function (schema, parentSchema) { var compiled = getCompiledSchemas(parentSchema); compiled.default = compileOrBoolean(schema); return function() { return true; }; }, valid: true, metaSchema: metaSchemaRef }); return ajv; function getCompiledSchemas(parentSchema, create) { var compiled; compiledCaseSchemas.some(function (c) { if (c.parentSchema === parentSchema) { compiled = c; return true; } }); if (!compiled && create !== false) { compiled = { parentSchema: parentSchema, cases: {}, default: true }; compiledCaseSchemas.push(compiled); } return compiled; } function compileOrBoolean(schema) { return typeof schema == 'boolean' ? schema : ajv.compile(schema); } }; ajv-keywords-3.4.1/keywords/switch.js000066400000000000000000000014611351017536700176640ustar00rootroot00000000000000'use strict'; var util = require('./_util'); module.exports = function defFunc(ajv) { if (ajv.RULES.keywords.switch && ajv.RULES.keywords.if) return; var metaSchemaRef = util.metaSchemaRef(ajv); defFunc.definition = { inline: require('./dotjs/switch'), statements: true, errors: 'full', metaSchema: { type: 'array', items: { required: [ 'then' ], properties: { 'if': metaSchemaRef, 'then': { anyOf: [ { type: 'boolean' }, metaSchemaRef ] }, 'continue': { type: 'boolean' } }, additionalProperties: false, dependencies: { 'continue': [ 'if' ] } } } }; ajv.addKeyword('switch', defFunc.definition); return ajv; }; ajv-keywords-3.4.1/keywords/transform.js000066400000000000000000000041501351017536700203740ustar00rootroot00000000000000'use strict'; module.exports = function defFunc (ajv) { var transform = { trimLeft: function (value) { return value.replace(/^[\s]+/, ''); }, trimRight: function (value) { return value.replace(/[\s]+$/, ''); }, trim: function (value) { return value.trim(); }, toLowerCase: function (value) { return value.toLowerCase(); }, toUpperCase: function (value) { return value.toUpperCase(); }, toEnumCase: function (value, cfg) { return cfg.hash[makeHashTableKey(value)] || value; } }; defFunc.definition = { type: 'string', errors: false, modifying: true, valid: true, compile: function (schema, parentSchema) { var cfg; if (schema.indexOf('toEnumCase') !== -1) { // build hash table to enum values cfg = {hash: {}}; // requires `enum` in schema if (!parentSchema.enum) throw new Error('Missing enum. To use `transform:["toEnumCase"]`, `enum:[...]` is required.'); for (var i = parentSchema.enum.length; i--; i) { var v = parentSchema.enum[i]; if (typeof v !== 'string') continue; var k = makeHashTableKey(v); // requires all `enum` values have unique keys if (cfg.hash[k]) throw new Error('Invalid enum uniqueness. To use `transform:["toEnumCase"]`, all values must be unique when case insensitive.'); cfg.hash[k] = v; } } return function (data, dataPath, object, key) { // skip if value only if (!object) return; // apply transform in order provided for (var j = 0, l = schema.length; j < l; j++) data = transform[schema[j]](data, cfg); object[key] = data; }; }, metaSchema: { type: 'array', items: { type: 'string', enum: [ 'trimLeft', 'trimRight', 'trim', 'toLowerCase', 'toUpperCase', 'toEnumCase' ] } } }; ajv.addKeyword('transform', defFunc.definition); return ajv; function makeHashTableKey (value) { return value.toLowerCase(); } }; ajv-keywords-3.4.1/keywords/typeof.js000066400000000000000000000014621351017536700176720ustar00rootroot00000000000000'use strict'; var KNOWN_TYPES = ['undefined', 'string', 'number', 'object', 'function', 'boolean', 'symbol']; module.exports = function defFunc(ajv) { defFunc.definition = { inline: function (it, keyword, schema) { var data = 'data' + (it.dataLevel || ''); if (typeof schema == 'string') return 'typeof ' + data + ' == "' + schema + '"'; schema = 'validate.schema' + it.schemaPath + '.' + keyword; return schema + '.indexOf(typeof ' + data + ') >= 0'; }, metaSchema: { anyOf: [ { type: 'string', enum: KNOWN_TYPES }, { type: 'array', items: { type: 'string', enum: KNOWN_TYPES } } ] } }; ajv.addKeyword('typeof', defFunc.definition); return ajv; }; ajv-keywords-3.4.1/keywords/uniqueItemProperties.js000066400000000000000000000034651351017536700225730ustar00rootroot00000000000000'use strict'; var SCALAR_TYPES = ['number', 'integer', 'string', 'boolean', 'null']; module.exports = function defFunc(ajv) { defFunc.definition = { type: 'array', compile: function(keys, parentSchema, it) { var equal = it.util.equal; var scalar = getScalarKeys(keys, parentSchema); return function(data) { if (data.length > 1) { for (var k=0; k < keys.length; k++) { var i, key = keys[k]; if (scalar[k]) { var hash = {}; for (i = data.length; i--;) { if (!data[i] || typeof data[i] != 'object') continue; var prop = data[i][key]; if (prop && typeof prop == 'object') continue; if (typeof prop == 'string') prop = '"' + prop; if (hash[prop]) return false; hash[prop] = true; } } else { for (i = data.length; i--;) { if (!data[i] || typeof data[i] != 'object') continue; for (var j = i; j--;) { if (data[j] && typeof data[j] == 'object' && equal(data[i][key], data[j][key])) return false; } } } } } return true; }; }, metaSchema: { type: 'array', items: {type: 'string'} } }; ajv.addKeyword('uniqueItemProperties', defFunc.definition); return ajv; }; function getScalarKeys(keys, schema) { return keys.map(function(key) { var properties = schema.items && schema.items.properties; var propType = properties && properties[key] && properties[key].type; return Array.isArray(propType) ? propType.indexOf('object') < 0 && propType.indexOf('array') < 0 : SCALAR_TYPES.indexOf(propType) >= 0; }); } ajv-keywords-3.4.1/package.json000066400000000000000000000025451351017536700164500ustar00rootroot00000000000000{ "name": "ajv-keywords", "version": "3.4.1", "description": "Custom JSON-Schema keywords for Ajv validator", "main": "index.js", "scripts": { "build": "node node_modules/ajv/scripts/compile-dots.js node_modules/ajv/lib keywords", "prepublish": "npm run build", "test": "npm run build && npm run eslint && npm run test-cov", "eslint": "eslint index.js keywords/*.js spec", "test-spec": "mocha spec/*.spec.js -R spec", "test-cov": "istanbul cover -x 'spec/**' node_modules/mocha/bin/_mocha -- spec/*.spec.js -R spec" }, "repository": { "type": "git", "url": "git+https://github.com/epoberezkin/ajv-keywords.git" }, "keywords": [ "JSON-Schema", "ajv", "keywords" ], "files": [ "index.js", "keywords" ], "author": "Evgeny Poberezkin", "license": "MIT", "bugs": { "url": "https://github.com/epoberezkin/ajv-keywords/issues" }, "homepage": "https://github.com/epoberezkin/ajv-keywords#readme", "peerDependencies": { "ajv": "^6.9.1" }, "devDependencies": { "ajv": "^6.9.1", "ajv-pack": "^0.3.0", "chai": "^4.2.0", "coveralls": "^3.0.2", "dot": "^1.1.1", "eslint": "^6.0.0", "glob": "^7.1.3", "istanbul": "^0.4.3", "js-beautify": "^1.8.9", "json-schema-test": "^2.0.0", "mocha": "^6.0.0", "pre-commit": "^1.1.3", "uuid": "^3.3.2" } } ajv-keywords-3.4.1/spec/000077500000000000000000000000001351017536700151065ustar00rootroot00000000000000ajv-keywords-3.4.1/spec/allRequired.spec.js000066400000000000000000000023511351017536700206470ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var ajvPack = require('ajv-pack'); var defFunc = require('../keywords/allRequired'); var defineKeywords = require('..'); var should = require('chai').should(); describe('keyword "allRequired"', function() { var ajvs = [ defFunc(new Ajv), defineKeywords(new Ajv, 'allRequired'), defineKeywords(new Ajv), defFunc(ajvPack.instance(new Ajv({sourceCode: true}))) ]; ajvs.forEach(function (ajv, i) { it('should validate that all defined properties are present #' + i, function() { var schema = { properties: { foo: true, bar: true }, allRequired: true }; ajv.validate(schema, {foo: 1, bar: 2}) .should.equal(true); ajv.validate(schema, {foo: 1}) .should.equal(false); }); }); ajvs.forEach(function (ajv, i) { it('should throw when properties is absent #' + i, function() { should.throw(function() { ajv.compile({ allRequired: true }); }); }); }); ajvs.forEach(function (ajv, i) { it('should throw when allRequired schema is invalid #' + i, function() { should.throw(function() { ajv.compile({ properties: {foo: true}, allRequired: 1 }); }); }); }); }); ajv-keywords-3.4.1/spec/async-tests.spec.js000066400000000000000000000020221351017536700206460ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var jsonSchemaTest = require('json-schema-test'); var defineKeywords = require('..'); var ajvs = [ defineKeywords(getAjv(), 'switch'), defineKeywords(getAjv()), defineKeywords(getAjv(true)) ]; jsonSchemaTest(ajvs, { description: 'keywords "switch" with async schemas', suites: { 'tests': './async-tests/{**/,}*.json' }, async: true, asyncValid: 'data', // afterError: after.error, // afterEach: after.each, cwd: __dirname, hideFolder: 'async-tests/' }); function getAjv(extras) { var ajv = new Ajv({ allErrors: extras, verbose: extras }); ajv.addKeyword('idExists', { async: true, type: 'number', validate: checkIdExists, errors: false }); return ajv; } function checkIdExists(schema, data) { switch (schema.table) { case 'users': return check([1, 5, 8]); case 'posts': return check([21, 25, 28]); default: throw new Error('no such table'); } function check(IDs) { return Promise.resolve(IDs.indexOf(data) >= 0); } } ajv-keywords-3.4.1/spec/async-tests/000077500000000000000000000000001351017536700173635ustar00rootroot00000000000000ajv-keywords-3.4.1/spec/async-tests/switch.json000066400000000000000000000014631351017536700215630ustar00rootroot00000000000000[ { "description": "switch: async + sync conditions", "schema": { "$async": true, "switch": [ { "if": { "idExists": { "table": "users" } }, "then": { "minimum": 6 } }, { "if": { "minimum": 21 }, "then": { "idExists": { "table": "posts" } } } ] }, "tests": [ { "description": "valid - first condition", "data": 8, "valid": true }, { "description": "valid - second condition", "data": 28, "valid": true }, { "description": "invalid - first condition", "data": 1, "valid": false }, { "description": "invalid - second condition", "data": 22, "valid": false } ] } ] ajv-keywords-3.4.1/spec/define_keywords.spec.js000066400000000000000000000014761351017536700215660ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var defineKeywords = require('..'); var should = require('chai').should(); describe('defineKeywords', function() { var ajv = new Ajv; it('should allow defining multiple keywords', function() { defineKeywords(ajv, ['typeof', 'instanceof']); ajv.validate({ typeof: 'undefined' }, undefined) .should.equal(true); ajv.validate({ typeof: 'undefined' }, {}) .should.equal(false); ajv.validate({ instanceof: 'Array' }, []) .should.equal(true); ajv.validate({ instanceof: 'Array' }, {}) .should.equal(false); }); it('should throw when unknown keyword is passed', function() { should.throw(function() { defineKeywords(ajv, 'unknownKeyword'); }); should.throw(function() { defineKeywords(ajv, ['typeof', 'unknownKeyword']); }); }); }); ajv-keywords-3.4.1/spec/dynamicDefaults.spec.js000066400000000000000000000155001351017536700215120ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var defFunc = require('../keywords/dynamicDefaults'); var defineKeywords = require('..'); var should = require('chai').should(); var assert = require('assert'); var uuid = require('uuid'); describe('keyword "dynamicDefaults"', function() { function getAjv() { return new Ajv({useDefaults: true, unknownFormats: true}); } var ajvs = [ defFunc(getAjv()), defineKeywords(getAjv(), 'dynamicDefaults'), defineKeywords(getAjv()) ]; ajvs.forEach(function (ajv, i) { it('should assign defaults #' + i, function (done) { var schema = { dynamicDefaults: { ts: 'timestamp', dt: 'datetime', d: 'date', t: 'time', r: 'random', ri: 'randomint', riN: { func: 'randomint', args: { max: 1000000 } }, s: 'seq', sN: { func: 'seq', args: { name: 'foo' } } } }; var validate = ajv.compile(schema); var data = {}; validate(data) .should.equal(true); test(data); data.s .should.equal(2*i); data.sN .should.equal(2*i); setTimeout(function() { var data1 = {}; validate(data1) .should.equal(true); test(data1); assert(data.ts < data1.ts); assert.notEqual(data.dt, data1.dt); assert.equal(data.d, data1.d); assert.notEqual(data.t, data1.t); assert.notEqual(data.r, data1.r); assert.notEqual(data.riN, data1.riN); data1.s .should.equal(2*i + 1); data1.sN .should.equal(2*i + 1); done(); }, 1000); function test(_data) { _data.ts .should.be.a('number'); assert(_data.ts <= Date.now()); ajv.validate({type: 'string', format: 'date-time'}, _data.dt) .should.equal(true); new Date(_data.dt) .should.be.a('Date'); ajv.validate({type: 'string', format: 'date'}, _data.d) .should.equal(true); (new Date).toISOString().indexOf(_data.d) .should.equal(0); ajv.validate({type: 'string', format: 'time'}, _data.t) .should.equal(true); _data.r .should.be.a('number'); assert(_data.r < 1); assert(_data.r >= 0); assert(_data.ri === 0 || _data.ri === 1); _data.riN .should.be.a('number'); assert.equal(Math.floor(_data.riN), _data.riN); assert(_data.riN < 1000000); assert(_data.riN >= 0); _data.s .should.be.a('number'); _data.sN .should.be.a('number'); } }); it('should NOT assign default if property is present #' + i, function() { var schema = { dynamicDefaults: { ts: 'timestamp' } }; var validate = ajv.compile(schema); var data = { ts: 123 }; validate(data) .should.equal(true); data.ts .should.equal(123); }); it('should NOT assign default inside anyOf etc. #' + i, function() { var schema = { anyOf: [ { dynamicDefaults: { ts: 'timestamp' } } ] }; var validate = ajv.compile(schema); var data = {}; validate(data) .should.equal(true); should.not.exist(data.ts); }); it('should fail schema compilation on unknown default #' + i, function() { var schema = { dynamicDefaults: { ts: 'unknown' } }; should.throw(function() { ajv.compile(schema); }); }); it('should allow adding defaults #' + i, function() { var schema = { dynamicDefaults: { id: 'uuid' } }; should.throw(function() { ajv.compile(schema); }); defFunc.definition.DEFAULTS.uuid = uuidV4; var data = {}; test(data); should.throw(function() { ajv.compile(schema); }); defineKeywords.get('dynamicDefaults').definition.DEFAULTS.uuid = uuidV4; var data1 = {}; test(data1); assert.notEqual(data.id, data1.id); function test(_data) { ajv.validate(schema, _data) .should.equal(true); ajv.validate({ format: 'uuid', type: 'string' }, _data.id) .should.equal(true); delete defFunc.definition.DEFAULTS.uuid; ajv.removeSchema(); } function uuidV4() { return uuid.v4(); } }); }); it('should NOT assign defaults when useDefaults is true/"shared and properties are null, empty or contain a value"', function() { var schema = { allOf: [ { dynamicDefaults: { ts: 'datetime', r: { func: 'randomint', args: { min: 5, max: 100000 } }, id: { func: 'seq', args: { name: 'id' } } } }, { type: 'object', properties: { ts: { type: 'string' }, r: { type: 'number', minimum: 5, exclusiveMaximum: 100000 }, id: { type: 'integer', minimum: 0 } } } ] }; var data = { ts: '', r: null, id: 3 }; test(new Ajv({useDefaults: true})); test(new Ajv({useDefaults: 'shared'})); function test(testAjv) { var validate = defFunc(testAjv).compile(schema); validate(data).should.equal(false); data.ts.should.equal(''); should.equal(data.r, null); data.id.should.equal(3); } }); it('should assign defaults when useDefaults = "empty" for properties that are undefined, null or empty strings', function(done) { var schema = { allOf: [ { dynamicDefaults: { ts: 'datetime', r: { func: 'randomint', args: { min: 5, max: 100000 } }, id: { func: 'seq', args: { name: 'id' } } } }, { type: 'object', properties: { ts: { type: 'string' }, r: { type: 'number', minimum: 5, exclusiveMaximum: 100000 }, id: { type: 'integer', minimum: 0 } } } ] }; var data = { ts: '', r: null }; var data1 = Object.assign({}, data); test(new Ajv({useDefaults: 'empty'})); function test(testAjv) { var validate = defFunc(testAjv).compile(schema); validate(data).should.equal(true); var tsRegex = /\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{3}Z/; data.ts.should.match(tsRegex); data.r.should.be.a('number'); data.id.should.be.a('number'); setTimeout(function(){ validate(data1).should.equal(true); data.ts.should.not.equal(data1.ts); data1.r.should.be.a('number'); //data.r and data1.r could match, but unlikely data.id.should.not.equal(data1.id); done(); }, 1000); } }); }); ajv-keywords-3.4.1/spec/formatLimit.spec.js000066400000000000000000000032301351017536700206620ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var defFunc = require('../keywords/formatMaximum'); var defineKeywords = require('..'); var should = require('chai').should(); describe('keywords "formatMinimum" and "formatMaximum"', function() { var ajvs = getAjvs(true); var ajvsFF = getAjvs(false); ajvs.forEach(function (ajv, i) { it('should not validate formatMaximum/Minimum if option format == false #' + i, function() { var ajvFF = ajvsFF[i]; var schema = { format: 'date', formatMaximum: '2015-08-01' }; var date = '2015-09-01'; ajv.validate(schema, date) .should.equal(false); ajvFF.validate(schema, date) .should.equal(true); }); }); ajvs.forEach(function (ajv, i) { it('should throw when "format" is absent #' + i, function() { should.throw(function() { ajv.compile({ formatMaximum: '2015-08-01' }); }); }); }); ajvs.forEach(function (ajv, i) { it('formatExclusiveMaximum should throw if not boolean #' + i, function() { should.throw(function() { ajv.compile({ formatMaximum: '2015-08-01', formatExclusiveMaximum: 1 }); }); }); }); ajvs.forEach(function (ajv, i) { it('formatExclusiveMaximum should throw when "formatMaximum" is absent #' + i, function() { should.throw(function() { ajv.compile({ formatExclusiveMaximum: true }); }); }); }); function getAjv(format) { return new Ajv({ allErrors: true, format: format }); } function getAjvs(format) { return [ defFunc(getAjv(format)), defineKeywords(getAjv(format), 'formatMaximum'), defineKeywords(getAjv(format)) ]; } }); ajv-keywords-3.4.1/spec/instanceof.spec.js000066400000000000000000000073521351017536700205350ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var defFunc = require('../keywords/instanceof'); var defineKeywords = require('..'); var should = require('chai').should(); describe('keyword "instanceof"', function() { var ajvs = [ defFunc(new Ajv), defineKeywords(new Ajv, 'instanceof'), defineKeywords(new Ajv) ]; ajvs.forEach(function (ajv, i) { it('should validate classes #' + i, function() { ajv.validate({ instanceof: 'Object' }, {}) .should.equal(true); ajv.validate({ instanceof: 'Object' }, []) .should.equal(true); ajv.validate({ instanceof: 'Object' }, 'foo') .should.equal(false); ajv.validate({ instanceof: 'Array' }, {}) .should.equal(false); ajv.validate({ instanceof: 'Array' }, []) .should.equal(true); ajv.validate({ instanceof: 'Array' }, 'foo') .should.equal(false); ajv.validate({ instanceof: 'Function' }, function(){}) .should.equal(true); ajv.validate({ instanceof: 'Function' }, []) .should.equal(false); ajv.validate({ instanceof: 'Number' }, new Number(42)) .should.equal(true); ajv.validate({ instanceof: 'Number' }, 42) .should.equal(false); ajv.validate({ instanceof: 'Number' }, 'foo') .should.equal(false); ajv.validate({ instanceof: 'String' }, new String('foo')) .should.equal(true); ajv.validate({ instanceof: 'String' }, 'foo') .should.equal(false); ajv.validate({ instanceof: 'String' }, 42) .should.equal(false); ajv.validate({ instanceof: 'Date' }, new Date) .should.equal(true); ajv.validate({ instanceof: 'Date' }, {}) .should.equal(false); ajv.validate({ instanceof: 'RegExp' }, /.*/) .should.equal(true); ajv.validate({ instanceof: 'RegExp' }, {}) .should.equal(false); ajv.validate({ instanceof: 'Buffer' }, new Buffer('foo')) .should.equal(true); ajv.validate({ instanceof: 'Buffer' }, 'foo') .should.equal(false); ajv.validate({ instanceof: 'Buffer' }, {}) .should.equal(false); ajv.validate({ instanceof: 'Buffer' }, {}) .should.equal(false); ajv.validate({ instanceof: 'Promise' }, new Promise(function(resolve, reject){ return resolve(); })) .should.equal(true); ajv.validate({ instanceof: 'Promise' }, function(){}) .should.equal(false); }); it('should validate multiple classes #' + i, function() { ajv.validate({ instanceof: ['Array', 'Function'] }, []) .should.equal(true); ajv.validate({ instanceof: ['Array', 'Function'] }, function(){}) .should.equal(true); ajv.validate({ instanceof: ['Array', 'Function'] }, {}) .should.equal(false); }); it('should allow adding classes #' + i, function() { function MyClass() {} should.throw(function() { ajv.compile({ instanceof: 'MyClass' }); }); defFunc.definition.CONSTRUCTORS.MyClass = MyClass; ajv.validate({ instanceof: 'MyClass' }, new MyClass) .should.equal(true); ajv.validate({ instanceof: 'Object' }, new MyClass) .should.equal(true); ajv.validate({ instanceof: 'MyClass' }, {}) .should.equal(false); delete defFunc.definition.CONSTRUCTORS.MyClass; ajv.removeSchema(); should.throw(function() { ajv.compile({ instanceof: 'MyClass' }); }); defineKeywords.get('instanceof').definition.CONSTRUCTORS.MyClass = MyClass; ajv.validate({ instanceof: 'MyClass' }, new MyClass) .should.equal(true); ajv.validate({ instanceof: 'Object' }, new MyClass) .should.equal(true); ajv.validate({ instanceof: 'MyClass' }, {}) .should.equal(false); delete defFunc.definition.CONSTRUCTORS.MyClass; ajv.removeSchema(); }); it('should throw when not string or array is passed #' + i, function() { should.throw(function() { ajv.compile({ instanceof: 1 }); }); }); }); }); ajv-keywords-3.4.1/spec/patternRequired.spec.js000066400000000000000000000021631351017536700215550ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var defFunc = require('../keywords/patternRequired'); var defineKeywords = require('..'); require('chai').should(); describe('keywords "patternRequired"', function() { var ajvs = getAjvs(); var ajvsOP = getAjvs(true); ajvs.forEach(function (ajv, i) { it('should only validate against own properties when using patternRequired #' + i, function() { var ajvOP = ajvsOP[i]; var schema = { patternRequired: [ 'f.*o' ] }; var baz = { foooo: false, fooooooo: 42.31 }; function FooThing() { this.bar = 123; } FooThing.prototype = baz; var object = new FooThing(); ajv.validate(schema, object).should.equal(true); ajvOP.validate(schema, object).should.equal(false); ajvOP.errors.should.have.length(1); }); }); function getAjv(ownProperties) { return new Ajv({ allErrors: true, ownProperties: ownProperties }); } function getAjvs(ownProperties) { return [ defFunc(getAjv(ownProperties)), defineKeywords(getAjv(ownProperties), 'patternRequired'), defineKeywords(getAjv(ownProperties)) ]; } }); ajv-keywords-3.4.1/spec/range.spec.js000066400000000000000000000032751351017536700175000ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var ajvPack = require('ajv-pack'); var defFunc = require('../keywords/range'); var defineKeywords = require('..'); var should = require('chai').should(); describe('keyword "range"', function() { var ajvs = [ defFunc(new Ajv), defineKeywords(new Ajv, 'range'), defineKeywords(new Ajv), defFunc(ajvPack.instance(new Ajv({sourceCode: true}))) ]; ajvs.forEach(function (ajv, i) { it('should validate that value is in range #' + i, function() { var schema = { range: [1, 3] }; ajv.validate(schema, 1) .should.equal(true); ajv.validate(schema, 2) .should.equal(true); ajv.validate(schema, 3) .should.equal(true); ajv.validate(schema, 0.99) .should.equal(false); ajv.validate(schema, 3.01) .should.equal(false); ajv.validate({ range: [1, 1] }, 1) .should.equal(true); var schemaExcl = { range: [1, 3], exclusiveRange: true }; ajv.validate(schemaExcl, 1) .should.equal(false); ajv.validate(schemaExcl, 2) .should.equal(true); ajv.validate(schemaExcl, 3) .should.equal(false); ajv.validate(schemaExcl, 1.01) .should.equal(true); ajv.validate(schemaExcl, 2.99) .should.equal(true); }); }); ajvs.forEach(function (ajv, i) { it('should throw when range schema is invalid #' + i, function() { [ { range: [1, '3'] }, { range: [1] }, { range: [1, 2, 3] }, { range: {} }, { range: [3, 1] }, { range: [1, 3], exclusiveRange: 'true' }, { range: [1, 1], exclusiveRange: true } ].forEach(function (schema) { should.throw(function() { ajv.compile(schema); }); }); }); }); }); ajv-keywords-3.4.1/spec/regexp.spec.js000066400000000000000000000036141351017536700176730ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var ajvPack = require('ajv-pack'); var defFunc = require('../keywords/regexp'); var defineKeywords = require('..'); var should = require('chai').should(); describe('keyword "regexp"', function() { var ajvs = [ defFunc(new Ajv), defineKeywords(new Ajv({allErrors: true}, 'regexp')), defineKeywords(new Ajv), defFunc(ajvPack.instance(new Ajv({sourceCode: true}))) ]; ajvs.forEach(function (ajv, i) { it('should validate that values match regular expressions with flags #' + i, function() { var schema = { type: 'object', properties: { foo: { regexp: '/foo/i' }, bar: { regexp: { pattern: 'bar', flags: 'i' } } } }; var validData = { foo: 'Food', bar: 'Barmen' }; var alsoValidData = { foo: 1, bar: 2 }; var invalidData = { foo: 'fog', bar: 'bad' }; ajv.validate(schema, {}) .should.equal(true); ajv.validate(schema, validData) .should.equal(true); ajv.validate(schema, alsoValidData) .should.equal(true); ajv.validate(schema, invalidData) .should.equal(false); }); }); ajvs.forEach(function (ajv, i) { it('should throw when regexp schema is invalid #' + i, function() { [ { regexp: '/foo' }, // invalid regexp { regexp: '/foo/a' }, // invalid regexp 2 { regexp: { pattern: '[a-z' } }, // invalid regexp { regexp: { pattern: '[a-z]', flags: 'a' } }, // invalid flag { regexp: { flag: 'i' } }, // missing pattern { regexp: { pattern: '[a-z]', flag: 'i', foo: 1 } }, // extra property { regexp: 1 }, // incorrect type { regexp: { pattern: 1, flags: 'i' } } // incorrect type ].forEach(function (schema) { should.throw(function() { ajv.compile(schema); }); }); }); }); }); ajv-keywords-3.4.1/spec/schema-tests.spec.js000066400000000000000000000020121351017536700207700ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var jsonSchemaTest = require('json-schema-test'); var defineKeywords = require('..'); var ajvs = [ defineKeywords(getAjv(), [ 'allRequired', 'anyRequired', 'oneRequired', 'deepProperties', 'deepRequired', 'formatMaximum', 'formatMinimum', 'patternRequired', 'prohibited', 'select', 'switch', 'uniqueItemProperties' ]), defineKeywords(getAjv()), defineKeywords(getAjv(true)), defineKeywords(getAjvNoMeta()) ]; jsonSchemaTest(ajvs, { description: 'json test suite', suites: { 'tests': './tests/{**/,}*.json' }, // afterError: after.error, // afterEach: after.each, cwd: __dirname, hideFolder: 'tests/' }); function getAjv(extras) { return new Ajv({ $data: true, allErrors: extras, verbose: extras, unknownFormats: ['allowedUnknown'] }); } function getAjvNoMeta() { return new Ajv({ $data: true, unknownFormats: ['allowedUnknown'], meta: false, validateSchema: false }); } ajv-keywords-3.4.1/spec/select.spec.js000066400000000000000000000022741351017536700176610ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var defFunc = require('../keywords/select'); var defineKeywords = require('..'); var should = require('chai').should(); describe('keyword "select"', function() { describe('invalid schema', function() { var ajvs = [ defFunc(new Ajv({$data: true})), defineKeywords(new Ajv({$data: true}), 'select'), defineKeywords(new Ajv({$data: true, allErrors: true})) ]; ajvs.forEach(function (ajv, i) { it('should throw during validation #' + i, function() { var validate = ajv.compile({ select: { $data: '0/type' } }); should.throw(function() { validate({type: 'foo'}); }); }); it('should NOT throw during validation #' + i, function() { var validate = ajv.compile({ select: { $data: '0/type' }, selectCases: { foo: true, bar: true }, selectDefault: false }); validate({type: 'foo'}) .should.equal(true); validate({type: 'bar'}) .should.equal(true); validate({type: 'unknown'}) .should.equal(false); validate({}) .should.equal(true); }); }); }); }); ajv-keywords-3.4.1/spec/tests/000077500000000000000000000000001351017536700162505ustar00rootroot00000000000000ajv-keywords-3.4.1/spec/tests/$data/000077500000000000000000000000001351017536700172255ustar00rootroot00000000000000ajv-keywords-3.4.1/spec/tests/$data/formatMaximum.json000066400000000000000000000344011351017536700227500ustar00rootroot00000000000000[ { "description": "formatMaximum in the property", "schema": { "properties": { "finalDate": { "format": "date", "formatMaximum": { "$data": "1/beforeThan" } }, "beforeThan": {} } }, "tests": [ { "description": "after the maximum date is invalid", "data": { "finalDate": "2015-11-09", "beforeThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is valid", "data": { "finalDate": "2015-08-17", "beforeThan": "2015-08-17" }, "valid": true }, { "description": "before the maximum date is valid", "data": { "finalDate": "2014-12-03", "beforeThan": "2015-08-17" }, "valid": true }, { "description": "ignores non-strings", "data": { "finalDate": 2015, "beforeThan": "2015-08-17" }, "valid": true }, { "description": "fails if value of formatMaximum is not string", "data": { "finalDate": "2014-12-03", "beforeThan": 2015 }, "valid": false }, { "description": "valid if value of formatMaximum is undefined", "data": { "finalDate": "2014-12-03" }, "valid": true } ] }, { "description": "formatMaximum in the property with formatExclusiveMaximum", "schema": { "properties": { "finalDate": { "format": "date", "formatMaximum": { "$data": "1/beforeThan" }, "formatExclusiveMaximum": true }, "beforeThan": {} } }, "tests": [ { "description": "after the maximum date is still invalid", "data": { "finalDate": "2015-11-09", "beforeThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is invalid", "data": { "finalDate": "2015-08-17", "beforeThan": "2015-08-17" }, "valid": false }, { "description": "before the maximum date is still valid", "data": { "finalDate": "2014-12-03", "beforeThan": "2015-08-17" }, "valid": true } ] }, { "description": "formatMaximum with format in the property", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMaximum": "2015-08-17" }, "whenFormat": {} } }, "tests": [ { "description": "after the maximum date is invalid", "data": { "when": "2015-11-09", "whenFormat": "date" }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date" }, "valid": true }, { "description": "before the maximum date is valid", "data": { "when": "2014-12-03", "whenFormat": "date" }, "valid": true }, { "description": "ignores non-strings", "data": { "when": 2015, "whenFormat": "date" }, "valid": true } ] }, { "description": "formatMaximum with format in the property and with formatExclusiveMaximum", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMaximum": "2015-08-17", "formatExclusiveMaximum": true }, "whenFormat": {} } }, "tests": [ { "description": "after the maximum date is still invalid", "data": { "when": "2015-11-09", "whenFormat": "date" }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date" }, "valid": false }, { "description": "before the maximum date is still valid", "data": { "when": "2014-12-03", "whenFormat": "date" }, "valid": true } ] }, { "description": "formatMaximum and format in the properties", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMaximum": { "$data": "1/beforeThan" } }, "whenFormat": {}, "beforeThan": {} } }, "tests": [ { "description": "after the maximum date is invalid", "data": { "when": "2015-11-09", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": true }, { "description": "before the maximum date is valid", "data": { "when": "2014-12-03", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": true } ] }, { "description": "formatMaximum and format in the properties with formatExclusiveMaximum", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMaximum": { "$data": "1/beforeThan" }, "formatExclusiveMaximum": true }, "whenFormat": {}, "beforeThan": {} } }, "tests": [ { "description": "after the maximum date is still invalid", "data": { "when": "2015-11-09", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": false }, { "description": "before the maximum date is still valid", "data": { "when": "2014-12-03", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": true } ] }, { "description": "formatExclusiveMaximum in the property", "schema": { "properties": { "finalDate": { "format": "date", "formatMaximum": "2015-08-17", "formatExclusiveMaximum": { "$data": "1/maxIsExclusive" } }, "maxIsExclusive": {} } }, "tests": [ { "description": "after the maximum date is invalid", "data": { "finalDate": "2015-11-09", "maxIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "finalDate": "2015-08-17" }, "valid": true }, { "description": "before the maximum date is valid", "data": { "finalDate": "2014-12-03" }, "valid": true }, { "description": "after the maximum date is still invalid", "data": { "finalDate": "2015-11-09", "maxIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "finalDate": "2015-08-17", "maxIsExclusive": true }, "valid": false }, { "description": "before the maximum date is still valid", "data": { "finalDate": "2014-12-03", "maxIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMaximum is not boolean", "data": { "finalDate": "2014-12-03", "maxIsExclusive": "false" }, "valid": false } ] }, { "description": "formatMaximum and formatExclusiveMaximum in the properties", "schema": { "properties": { "finalDate": { "format": "date", "formatMaximum": { "$data": "1/beforeThan" }, "formatExclusiveMaximum": { "$data": "1/maxIsExclusive" } }, "beforeThan": {}, "maxIsExclusive": {} } }, "tests": [ { "description": "after the maximum date is invalid", "data": { "finalDate": "2015-11-09", "beforeThan": "2015-08-17", "maxIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "finalDate": "2015-08-17", "beforeThan": "2015-08-17" }, "valid": true }, { "description": "before the maximum date is valid", "data": { "finalDate": "2014-12-03", "beforeThan": "2015-08-17" }, "valid": true }, { "description": "after the maximum date is still invalid", "data": { "finalDate": "2015-11-09", "beforeThan": "2015-08-17", "maxIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "finalDate": "2015-08-17", "beforeThan": "2015-08-17", "maxIsExclusive": true }, "valid": false }, { "description": "before the maximum date is still valid", "data": { "finalDate": "2014-12-03", "beforeThan": "2015-08-17", "maxIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMaximum is not boolean", "data": { "finalDate": "2014-12-03", "beforeThan": "2015-08-17", "maxIsExclusive": "false" }, "valid": false }, { "description": "fails if value of formatMaximum is not string", "data": { "finalDate": "2014-12-03", "beforeThan": 2015, "maxIsExclusive": false }, "valid": false } ] }, { "description": "formatMaximum with format and formatExclusiveMaximum in the properties", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMaximum": "2015-08-17", "formatExclusiveMaximum": { "$data": "1/maxIsExclusive" } }, "whenFormat": {}, "maxIsExclusive": {} } }, "tests": [ { "description": "after the maximum date is invalid", "data": { "when": "2015-11-09", "whenFormat": "date", "maxIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date" }, "valid": true }, { "description": "before the maximum date is valid", "data": { "when": "2014-12-03", "whenFormat": "date" }, "valid": true }, { "description": "after the maximum date is still invalid", "data": { "when": "2015-11-09", "whenFormat": "date", "maxIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date", "maxIsExclusive": true }, "valid": false }, { "description": "before the maximum date is still valid", "data": { "when": "2014-12-03", "whenFormat": "date", "maxIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMaximum is not boolean", "data": { "when": "2014-12-03", "whenFormat": "date", "maxIsExclusive": "false" }, "valid": false } ] }, { "description": "formatMaximum, format and formatExclusiveMaximum in the properties", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMaximum": { "$data": "1/beforeThan" }, "formatExclusiveMaximum": { "$data": "1/maxIsExclusive" } }, "beforeThan": {}, "whenFormat": {}, "maxIsExclusive": {} } }, "tests": [ { "description": "after the maximum date is invalid", "data": { "when": "2015-11-09", "whenFormat": "date", "beforeThan": "2015-08-17", "maxIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": true }, { "description": "before the maximum date is valid", "data": { "when": "2014-12-03", "whenFormat": "date", "beforeThan": "2015-08-17" }, "valid": true }, { "description": "after the maximum date is still invalid", "data": { "when": "2015-11-09", "whenFormat": "date", "beforeThan": "2015-08-17", "maxIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date", "beforeThan": "2015-08-17", "maxIsExclusive": true }, "valid": false }, { "description": "before the maximum date is still valid", "data": { "when": "2014-12-03", "whenFormat": "date", "beforeThan": "2015-08-17", "maxIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMaximum is not boolean", "data": { "when": "2014-12-03", "whenFormat": "date", "beforeThan": "2015-08-17", "maxIsExclusive": "false" }, "valid": false } ] } ] ajv-keywords-3.4.1/spec/tests/$data/formatMinimum.json000066400000000000000000000340511351017536700227470ustar00rootroot00000000000000[ { "description": "formatMinimum in the property", "schema": { "properties": { "finalDate": { "format": "date", "formatMinimum": { "$data": "1/laterThan" } }, "laterThan": {} } }, "tests": [ { "description": "before the minimum date is invalid", "data": { "finalDate": "2014-12-03", "laterThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is valid", "data": { "finalDate": "2015-08-17", "laterThan": "2015-08-17" }, "valid": true }, { "description": "after the minimum date is valid", "data": { "finalDate": "2015-11-09", "laterThan": "2015-08-17" }, "valid": true }, { "description": "ignores non-strings", "data": { "finalDate": 2015, "laterThan": "2015-08-17" }, "valid": true }, { "description": "fails if value of formatMinimum is not string", "data": { "finalDate": "2016-11-09", "laterThan": 2015 }, "valid": false } ] }, { "description": "formatMinimum in the property with formatExclusiveMinimum", "schema": { "properties": { "finalDate": { "format": "date", "formatMinimum": { "$data": "1/laterThan" }, "formatExclusiveMinimum": true }, "laterThan": {} } }, "tests": [ { "description": "before the minimum date is still invalid", "data": { "finalDate": "2014-12-03", "laterThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is invalid", "data": { "finalDate": "2015-08-17", "laterThan": "2015-08-17" }, "valid": false }, { "description": "after the minimum date is still valid", "data": { "finalDate": "2015-11-09", "laterThan": "2015-08-17" }, "valid": true } ] }, { "description": "formatMinimum with format in the property", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMinimum": "2015-08-17" }, "whenFormat": {} } }, "tests": [ { "description": "before the minimum date is invalid", "data": { "when": "2014-12-03", "whenFormat": "date" }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date" }, "valid": true }, { "description": "after the minimum date is valid", "data": { "when": "2015-11-09", "whenFormat": "date" }, "valid": true }, { "description": "ignores non-strings", "data": { "when": 2015, "whenFormat": "date" }, "valid": true } ] }, { "description": "formatMinimum with format in the property and with formatExclusiveMinimum", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMinimum": "2015-08-17", "formatExclusiveMinimum": true }, "whenFormat": {} } }, "tests": [ { "description": "before the minimum date is still invalid", "data": { "when": "2014-12-03", "whenFormat": "date" }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date" }, "valid": false }, { "description": "after the minimum date is still valid", "data": { "when": "2015-11-09", "whenFormat": "date" }, "valid": true } ] }, { "description": "formatMinimum and format in the properties", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMinimum": { "$data": "1/laterThan" } }, "whenFormat": {}, "laterThan": {} } }, "tests": [ { "description": "before the minimum date is invalid", "data": { "when": "2014-12-03", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": true }, { "description": "after the minimum date is valid", "data": { "when": "2015-11-09", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": true } ] }, { "description": "formatMinimum and format in the properties with formatExclusiveMinimum", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMinimum": { "$data": "1/laterThan" }, "formatExclusiveMinimum": true }, "whenFormat": {}, "laterThan": {} } }, "tests": [ { "description": "before the minimum date is still invalid", "data": { "when": "2014-12-03", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": false }, { "description": "after the minimum date is still valid", "data": { "when": "2015-11-09", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": true } ] }, { "description": "formatExclusiveMinimum in the property", "schema": { "properties": { "finalDate": { "format": "date", "formatMinimum": "2015-08-17", "formatExclusiveMinimum": { "$data": "1/minIsExclusive" } }, "minIsExclusive": {} } }, "tests": [ { "description": "before the minimum date is invalid", "data": { "finalDate": "2014-12-03", "minIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "finalDate": "2015-08-17" }, "valid": true }, { "description": "after the minimum date is valid", "data": { "finalDate": "2015-11-09" }, "valid": true }, { "description": "before the minimum date is still invalid", "data": { "finalDate": "2014-12-03", "minIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "finalDate": "2015-08-17", "minIsExclusive": true }, "valid": false }, { "description": "after the minimum date is still valid", "data": { "finalDate": "2015-11-09", "minIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMinimum is not boolean", "data": { "finalDate": "2015-11-09", "minIsExclusive": "false" }, "valid": false } ] }, { "description": "formatMinimum and formatExclusiveMinimum in the properties", "schema": { "properties": { "finalDate": { "format": "date", "formatMinimum": { "$data": "1/laterThan" }, "formatExclusiveMinimum": { "$data": "1/minIsExclusive" } }, "laterThan": {}, "minIsExclusive": {} } }, "tests": [ { "description": "before the minimum date is invalid", "data": { "finalDate": "2014-12-03", "laterThan": "2015-08-17", "minIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "finalDate": "2015-08-17", "laterThan": "2015-08-17" }, "valid": true }, { "description": "after the minimum date is valid", "data": { "finalDate": "2015-11-09", "laterThan": "2015-08-17" }, "valid": true }, { "description": "before the minimum date is still invalid", "data": { "finalDate": "2014-12-03", "laterThan": "2015-08-17", "minIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "finalDate": "2015-08-17", "laterThan": "2015-08-17", "minIsExclusive": true }, "valid": false }, { "description": "after the minimum date is still valid", "data": { "finalDate": "2015-11-09", "laterThan": "2015-08-17", "minIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMinimum is not boolean", "data": { "finalDate": "2015-11-09", "laterThan": "2015-08-17", "minIsExclusive": "false" }, "valid": false }, { "description": "fails if value of formatMinimum is not string", "data": { "finalDate": "2016-11-09", "laterThan": 2015, "minIsExclusive": false }, "valid": false } ] }, { "description": "formatMinimum with format and formatExclusiveMinimum in the properties", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMinimum": "2015-08-17", "formatExclusiveMinimum": { "$data": "1/minIsExclusive" } }, "whenFormat": {}, "minIsExclusive": {} } }, "tests": [ { "description": "before the minimum date is invalid", "data": { "when": "2014-12-03", "whenFormat": "date", "minIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date" }, "valid": true }, { "description": "after the minimum date is valid", "data": { "when": "2015-11-09", "whenFormat": "date" }, "valid": true }, { "description": "before the minimum date is still invalid", "data": { "when": "2014-12-03", "whenFormat": "date", "minIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date", "minIsExclusive": true }, "valid": false }, { "description": "after the minimum date is still valid", "data": { "when": "2015-11-09", "whenFormat": "date", "minIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMinimum is not boolean", "data": { "when": "2015-11-09", "whenFormat": "date", "minIsExclusive": "false" }, "valid": false } ] }, { "description": "formatMinimum, format and formatExclusiveMinimum in the properties", "schema": { "properties": { "when": { "format": { "$data": "1/whenFormat" }, "formatMinimum": { "$data": "1/laterThan" }, "formatExclusiveMinimum": { "$data": "1/minIsExclusive" } }, "laterThan": {}, "whenFormat": {}, "minIsExclusive": {} } }, "tests": [ { "description": "before the minimum date is invalid", "data": { "when": "2014-12-03", "whenFormat": "date", "laterThan": "2015-08-17", "minIsExclusive": false }, "valid": false }, { "description": "boundary point is valid", "data": { "when": "2015-08-17", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": true }, { "description": "after the minimum date is valid", "data": { "when": "2015-11-09", "whenFormat": "date", "laterThan": "2015-08-17" }, "valid": true }, { "description": "before the minimum date is still invalid", "data": { "when": "2014-12-03", "whenFormat": "date", "laterThan": "2015-08-17", "minIsExclusive": true }, "valid": false }, { "description": "boundary point is invalid", "data": { "when": "2015-08-17", "whenFormat": "date", "laterThan": "2015-08-17", "minIsExclusive": true }, "valid": false }, { "description": "after the minimum date is still valid", "data": { "when": "2015-11-09", "whenFormat": "date", "laterThan": "2015-08-17", "minIsExclusive": true }, "valid": true }, { "description": "fails if value of formatExclusiveMinimum is not boolean", "data": { "when": "2015-11-09", "whenFormat": "date", "laterThan": "2015-08-17", "minIsExclusive": "false" }, "valid": false } ] } ] ajv-keywords-3.4.1/spec/tests/allRequired.json000066400000000000000000000042571351017536700214240ustar00rootroot00000000000000[ { "description": "allRequired: true requires the presense of all defined properties", "schema": { "properties": { "foo": true, "bar": true }, "allRequired": true }, "tests": [ { "description": "all defined properties present is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "all defined properties present with an additional property is valid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": true }, { "description": "some of defined properties present is invalid", "data": {"foo": 1}, "valid": false }, { "description": "some of defined properties present with an additional property is invalid", "data": {"foo": 1, "baz": 3}, "valid": false }, { "description": "none of defined properties present is invalid", "data": {"baz": 3}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false } ] }, { "description": "allRequired: false is always ignored", "schema": { "properties": { "foo": true, "bar": true }, "allRequired": false }, "tests": [ { "description": "all defined properties present is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "all defined properties present with an additional property is valid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": true }, { "description": "some of defined properties present is valid", "data": {"foo": 1}, "valid": true }, { "description": "some of defined properties present with an additional property is valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "none of defined properties present is valid", "data": {"baz": 3}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/anyRequired.json000066400000000000000000000037221351017536700214370ustar00rootroot00000000000000[ { "description": "anyRequired requires that at least on property in the list is present", "schema": { "anyRequired": ["foo"] }, "tests": [ { "description": "property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "property present with an additional property is valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "no property present is invalid", "data": { "baz": 1 }, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false } ] }, { "description": "multiple properties in prohibited", "schema": { "anyRequired": ["foo", "bar"] }, "tests": [ { "description": "property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "property present with an additional property is valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "all properties present is valid", "data": {"foo": 1, "bar": 2}, "valid": true }, { "description": "all properties present with an additional property is valid", "data": {"foo": 1, "bar": 2, "baz": 3}, "valid": true }, { "description": "no property present is invalid", "data": {"baz": 3}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false } ] }, { "description": "anyRequired: [] is always valid", "schema": { "anyRequired": [] }, "tests": [ { "description": "any object is valid", "data": {"foo": 1}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/deepProperties.json000066400000000000000000000171011351017536700221350ustar00rootroot00000000000000[ { "description": "deepProperties keyword validation", "schema": { "type": "object", "deepProperties": { "/foo/bar": { "type": "number" }, "/foo/baz": { "type": "string" }, "/quux": { "type": "boolean" } } }, "tests": [ { "description": "object with all valid properties is valid", "data": { "foo": { "bar": 1, "baz": "2" }, "quux": true }, "valid": true }, { "description": "object with some valid properties is valid", "data": { "foo": { "bar": 1 }, "quux": true }, "valid": true }, { "description": "object with all invalid properties is invalid", "data": { "foo": { "bar": null, "baz": null }, "quux": null }, "valid": false }, { "description": "object with one invalid property is invalid", "data": { "quux": null }, "valid": false }, { "description": "object with one invalid sub-property is invalid", "data": { "foo": { "bar": null }, "quux": true }, "valid": false } ] }, { "description": "deepProperties keyword with items", "schema": { "type": "object", "properties": { "inside": { "type": "object", "deepProperties": { "/foo/1/bar": { "type": "number" }, "/foo/2/baz": { "type": "string" }, "/quux/3": { "type": "boolean" } } } } }, "tests": [ { "description": "object with all valid properties/items is valid", "data": { "inside": { "foo": [ {}, { "bar": 1 }, { "baz": "2" } ], "quux": [ 0, 0, 0, true ] } }, "valid": true }, { "description": "object with some valid properties/items is valid", "data": { "inside": { "foo": [ {}, { "bar": 1 } ], "quux": [ 0, 0, 0, true ] } }, "valid": true }, { "description": "object with all invalid properties is invalid", "data": { "inside": { "foo": [ {}, { "bar": null }, { "baz": null } ], "quux": [ 0, 0, 0, null ] } }, "valid": false }, { "description": "object with one invalid property is invalid", "data": { "inside": { "foo": [ {}, { "bar": 1 }, { "baz": "2" } ], "quux": [ 0, 0, 0, null ] } }, "valid": false }, { "description": "object with one invalid sub-property is invalid", "data": { "inside": { "foo": [ {}, { "bar": 1 }, { "baz": null } ], "quux": [ 0, 0, 0, true ] } }, "valid": false } ] }, { "description": "deepProperties keyword with empty sub-properties", "schema": { "type": "array", "items": { "type": "object", "deepProperties": { "/": { "type": "number" }, "/foo/": { "type": "string" }, "/bar//baz": { "type": "boolean" } } } }, "tests": [ { "description": "object with all valid properties is valid", "data": [ { "": 1, "foo": { "": "2" }, "bar": { "": { "baz": true } } } ], "valid": true }, { "description": "object with some valid properties is valid", "data": [ { "": 1, "bar": { "": { "baz": true } } } ], "valid": true }, { "description": "object with all invalid properties is invalid", "data": [ { "": null, "foo": { "": null }, "bar": { "": { "baz": null } } } ], "valid": false }, { "description": "object with one invalid property is invalid", "data": [ { "": null, "foo": { "": "2" }, "bar": { "": { "baz": true } } } ], "valid": false }, { "description": "object with one invalid sub-property is invalid", "data": [ { "": 1, "foo": { "": "2" }, "bar": { "": { "baz": null } } } ], "valid": false } ] }, { "description": "deepProperties keyword with numbered properties", "schema": { "type": "object", "properties": { "inside": { "type": "object", "deepProperties": { "/foo/1/bar": { "type": "number" }, "/foo/2/baz": { "type": "string" }, "/quux/3": { "type": "boolean" } } } } }, "tests": [ { "description": "object with all valid properties is valid", "data": { "inside": { "foo": { "1": { "bar": 1 }, "2": { "baz": "2" } }, "quux": { "3": true } } }, "valid": true }, { "description": "object with some valid properties is valid", "data": { "inside": { "foo": { "1": { "bar": 1 } }, "quux": { "3": true } } }, "valid": true }, { "description": "object with all invalid properties is invalid", "data": { "inside": { "foo": { "1": { "bar": null }, "2": { "baz": null } }, "quux": { "3": null } } }, "valid": false }, { "description": "object with one invalid property is invalid", "data": { "inside": { "foo": { "1": { "bar": 1 }, "2": { "baz": "2" } }, "quux": { "3": null } } }, "valid": false }, { "description": "object with one invalid sub-property is invalid", "data": { "inside": { "foo": { "1": { "bar": 1 }, "2": { "baz": null } }, "quux": { "3": true } } }, "valid": false } ] }, { "description": "deepProperties keyword with non-objects", "schema": { "deepProperties": { "/foo/bar": { "type": "number" } } }, "tests": [ { "description": "non-object is valid", "data": 1, "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/deepRequired.json000066400000000000000000000076141351017536700215710ustar00rootroot00000000000000[ { "description": "deepRequired keyword validation", "schema": { "type": "object", "deepRequired": [ "/foo/bar", "/foo/baz", "/quux" ] }, "tests": [ { "description": "object with all required properties is valid", "data": { "foo": { "bar": 1, "baz": 2 }, "quux": 3 }, "valid": true }, { "description": "object without any required properties is invalid", "data": { "foo": {} }, "valid": false }, { "description": "object with one required property is invalid", "data": { "quux": 3 }, "valid": false }, { "description": "object with one required sub-property is invalid", "data": { "foo": { "bar": 1 }, "quux": 3 }, "valid": false } ] }, { "description": "deepRequired keyword with items", "schema": { "type": "object", "properties": { "inside": { "type": "object", "deepRequired": [ "/foo/1/bar", "/foo/2/baz", "/quux/3" ] } } }, "tests": [ { "description": "object with all required properties/items is valid", "data": { "inside": { "foo": [ {}, { "bar": 1 }, { "baz": 2 } ], "quux": [ 0, 1, 2, 3 ] } }, "valid": true }, { "description": "object without any required properties is invalid", "data": { "inside": { "foo": [{}, {}, {}], "quux": [0, 1, 2] } }, "valid": false }, { "description": "object with one required property is invalid", "data": { "inside": { "quux": [ 0, 1, 2, 3 ] } }, "valid": false }, { "description": "object with one required sub-property is invalid", "data": { "inside": { "foo": [ {}, { "bar": 1 }, {} ], "quux": [ 0, 1, 2, 3 ] } }, "valid": false } ] }, { "description": "deepRequired keyword with empty sub-properties", "schema": { "type": "array", "items": { "type": "object", "deepRequired": [ "/", "/foo/", "/bar//baz" ] } }, "tests": [ { "description": "object with required properties is valid", "data": [ { "": 0, "foo": { "": 1 }, "bar": { "": { "baz": 2 } } } ], "valid": true }, { "description": "object without any required properties is invalid", "data": [ { "foo": {}, "bar": { "": {} } } ], "valid": false }, { "description": "object with one required property is invalid", "data": [ { "": 0, "foo": {}, "bar": { "": {} } } ], "valid": false }, { "description": "object with one required sub-property is invalid", "data": [ { "": 0, "foo": { "": 1 }, "bar": { "": {} } } ], "valid": false } ] }, { "description": "deepRequired keyword with non-objects", "schema": { "deepRequired": [ "/foo/bar" ] }, "tests": [ { "description": "non-object is valid", "data": 1, "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/formatMaximum.json000066400000000000000000000126671351017536700220050ustar00rootroot00000000000000[ { "description": "formatMaximum validation with date format", "schema": { "format": "date", "formatMaximum": "2015-08-17" }, "tests": [ { "description": "after the maximum date is invalid", "data": "2015-11-09", "valid": false }, { "description": "boundary point is valid", "data": "2015-08-17", "valid": true }, { "description": "before the maximum date is valid", "data": "2014-12-03", "valid": true }, { "description": "ignores non-strings", "data": 2015, "valid": true } ] }, { "description": "formatExclusiveMaximum validation with date format", "schema": { "format": "date", "formatMaximum": "2015-08-17", "formatExclusiveMaximum": true }, "tests": [ { "description": "after the maximum date is still invalid", "data": "2015-11-09", "valid": false }, { "description": "boundary point is invalid", "data": "2015-08-17", "valid": false }, { "description": "before the maximum date is still valid", "data": "2014-12-03", "valid": true } ] }, { "description": "formatMaximum validation with time format", "schema": { "format": "time", "formatMaximum": "13:15:17.000Z" }, "tests": [ { "description": "time after the maximum time is invalid", "data": "15:11:09.000Z", "valid": false }, { "description": "boundary point is valid", "data": "13:15:17.000Z", "valid": true }, { "description": "boundary point is valid, timezone is ignored", "data": "13:15:17.000+01:00", "valid": true }, { "description": "boundary point is valid, no timezone is ok too", "data": "13:15:17.000", "valid": true }, { "description": "time before the maximum time is valid", "data": "10:33:55.000Z", "valid": true }, { "description": "ignores non-strings", "data": 1315, "valid": true } ] }, { "description": "formatExclusiveMaximum validation with time format", "schema": { "format": "time", "formatMaximum": "13:15:17.000Z", "formatExclusiveMaximum": true }, "tests": [ { "description": "time after the maximum time is still invalid", "data": "15:11:09.000Z", "valid": false }, { "description": "boundary point is invalid", "data": "13:15:17.000Z", "valid": false }, { "description": "boundary point is invalid, timezone is ignored", "data": "13:15:17.000+01:00", "valid": false }, { "description": "boundary point is invalid, no timezone is ok too", "data": "13:15:17.000", "valid": false }, { "description": "time before the maximum time is still valid", "data": "10:33:55.000Z", "valid": true } ] }, { "description": "formatMaximum validation with date-time format", "schema": { "format": "date-time", "formatMaximum": "2015-08-17T13:15:17.000Z" }, "tests": [ { "description": "date after the maximum date is invalid", "data": "2015-11-09T13:15:17.000Z", "valid": false }, { "description": "same date, time after the maximum time is invalid", "data": "2015-08-17T15:11:09.000Z", "valid": false }, { "description": "boundary point is valid", "data": "2015-08-17T13:15:17.000Z", "valid": true }, { "description": "same date, time before the maximum time is valid", "data": "2015-08-17T10:33:55.000Z", "valid": true }, { "description": "date before the maximum date is valid", "data": "2014-12-03T13:15:17.000Z", "valid": true }, { "description": "ignores non-strings", "data": 2015, "valid": true } ] }, { "description": "formatExclusiveMaximum validation with date-time format", "schema": { "format": "date-time", "formatMaximum": "2015-08-17T13:15:17.000Z", "formatExclusiveMaximum": true }, "tests": [ { "description": "date after the maximum date is still invalid", "data": "2015-11-09T13:15:17.000Z", "valid": false }, { "description": "same date, time after the maximum time is still invalid", "data": "2015-08-17T15:11:09.000Z", "valid": false }, { "description": "boundary point is invalid", "data": "2015-08-17T13:15:17.000Z", "valid": false }, { "description": "same date, time before the maximum time is still valid", "data": "2015-08-17T10:33:55.000Z", "valid": true }, { "description": "date before the maximum date is still valid", "data": "2014-12-03T13:15:17.000Z", "valid": true } ] }, { "description": "formatMaximum is valid with whitelisted unknown format", "schema": { "format": "allowedUnknown", "formatMaximum": "2015" }, "tests": [ { "description": "valid string", "data": "2016", "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/formatMinimum.json000066400000000000000000000122171351017536700217720ustar00rootroot00000000000000[ { "description": "formatMinimum validation with date format", "schema": { "format": "date", "formatMinimum": "2015-08-17" }, "tests": [ { "description": "after the minimum date is valid", "data": "2015-11-09", "valid": true }, { "description": "boundary point is valid", "data": "2015-08-17", "valid": true }, { "description": "before the minimum date is invalid", "data": "2014-12-03", "valid": false }, { "description": "ignores non-strings", "data": 2015, "valid": true } ] }, { "description": "formatExclusiveMinimum validation with date format", "schema": { "format": "date", "formatMinimum": "2015-08-17", "formatExclusiveMinimum": true }, "tests": [ { "description": "after the minimum date is still valid", "data": "2015-11-09", "valid": true }, { "description": "boundary point is invalid", "data": "2015-08-17", "valid": false }, { "description": "before the minimum date is still invalid", "data": "2014-12-03", "valid": false } ] }, { "description": "formatMinimum validation with time format", "schema": { "format": "time", "formatMinimum": "13:15:17.000Z" }, "tests": [ { "description": "time after the minimum time is valid", "data": "15:11:09.000Z", "valid": true }, { "description": "boundary point is valid", "data": "13:15:17.000Z", "valid": true }, { "description": "boundary point is valid, timezone is ignored", "data": "13:15:17.000+01:00", "valid": true }, { "description": "boundary point is valid, no timezone is ok too", "data": "13:15:17.000", "valid": true }, { "description": "time before the minimum time is invalid", "data": "10:33:55.000Z", "valid": false }, { "description": "ignores non-strings", "data": 1315, "valid": true } ] }, { "description": "formatExclusiveMinimum validation with time format", "schema": { "format": "time", "formatMinimum": "13:15:17.000Z", "formatExclusiveMinimum": true }, "tests": [ { "description": "time after the minimum time is still valid", "data": "15:11:09.000Z", "valid": true }, { "description": "boundary point is invalid", "data": "13:15:17.000Z", "valid": false }, { "description": "boundary point is invalid, timezone is ignored", "data": "13:15:17.000+01:00", "valid": false }, { "description": "boundary point is invalid, no timezone is ok too", "data": "13:15:17.000", "valid": false }, { "description": "time before the minimum time is still invalid", "data": "10:33:55.000Z", "valid": false } ] }, { "description": "formatMinimum validation with date-time format", "schema": { "format": "date-time", "formatMinimum": "2015-08-17T13:15:17.000Z" }, "tests": [ { "description": "date after the minimum date is valid", "data": "2015-11-09T13:15:17.000Z", "valid": true }, { "description": "same date, time after the minimum time is valid", "data": "2015-08-17T15:11:09.000Z", "valid": true }, { "description": "boundary point is valid", "data": "2015-08-17T13:15:17.000Z", "valid": true }, { "description": "same date, time before the minimum time is invalid", "data": "2015-08-17T10:33:55.000Z", "valid": false }, { "description": "date before the minimum date is invalid", "data": "2014-12-03T13:15:17.000Z", "valid": false }, { "description": "ignores non-strings", "data": 2015, "valid": true } ] }, { "description": "formatExclusiveMinimum validation with date-time format", "schema": { "format": "date-time", "formatMinimum": "2015-08-17T13:15:17.000Z", "formatExclusiveMinimum": true }, "tests": [ { "description": "date after the minimum date is still valid", "data": "2015-11-09T13:15:17.000Z", "valid": true }, { "description": "same date, time after the minimum time is still valid", "data": "2015-08-17T15:11:09.000Z", "valid": true }, { "description": "boundary point is invalid", "data": "2015-08-17T13:15:17.000Z", "valid": false }, { "description": "same date, time before the minimum time is stillinvalid", "data": "2015-08-17T10:33:55.000Z", "valid": false }, { "description": "date before the minimum date is still invalid", "data": "2014-12-03T13:15:17.000Z", "valid": false } ] } ] ajv-keywords-3.4.1/spec/tests/oneRequired.json000066400000000000000000000034551351017536700214340ustar00rootroot00000000000000[ { "description": "oneRequired requires that at least on property in the list is present", "schema": { "oneRequired": ["foo"] }, "tests": [ { "description": "property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "property present with an additional property is valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "no property present is invalid", "data": { "baz": 1 }, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false } ] }, { "description": "multiple properties in prohibited", "schema": { "oneRequired": ["foo", "bar"] }, "tests": [ { "description": "property present is valid", "data": {"foo": 1}, "valid": true }, { "description": "property present with an additional property is valid", "data": {"foo": 1, "baz": 3}, "valid": true }, { "description": "multiple properties present is invalid", "data": {"foo": 1, "bar": 2}, "valid": false }, { "description": "no property present is invalid", "data": {"baz": 3}, "valid": false }, { "description": "empty object is invalid", "data": {}, "valid": false } ] }, { "description": "oneRequired: [] is always valid", "schema": { "oneRequired": [] }, "tests": [ { "description": "any object is valid", "data": {"foo": 1}, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/patternRequired.json000066400000000000000000000042741351017536700223300ustar00rootroot00000000000000[ { "description": "patternRequired requires that some property matching pattern is present", "schema": { "patternRequired": [ "f.*o" ] }, "tests": [ { "description": "property matching required pattern is valid", "data": { "foo": 1 }, "valid": true }, { "description": "one of properties matching required pattern is valid", "data": { "foo": 1, "bar": 2 }, "valid": true }, { "description": "non-present property matching required pattern is invalid", "data": { "bar": 1 }, "valid": false } ] }, { "description": "multiple patterns in patternRequired", "schema": { "patternRequired": [ "a+", "b+" ] }, "tests": [ { "description": "both patterns matched with one property is valid", "data": { "ab": 2 }, "valid": true }, { "description": "both patterns matched with separate properties is valid", "data": { "aa": 1, "bb": 2 }, "valid": true }, { "description": "both patterns matched with multiple properties is valid", "data": { "a": 1, "aa": 2, "ab": 3, "b": 4, "bb": 5 }, "valid": true }, { "description": "one pattern not matched is invalid", "data": { "aa": 1 }, "valid": false }, { "description": "another pattern not matched is invalid", "data": { "bb": 2 }, "valid": false }, { "description": "both patterns not matched is invalid", "data": { "c": 3 }, "valid": false } ] }, { "description": "regexes in patternRequired are not anchored by default and are case sensitive", "schema": { "patternRequired": [ "X_[0-9]{2,}" ] }, "tests": [ { "description": "regexes are not anchored", "data": { "aX_25b": 1 }, "valid": true }, { "description": "regexes are case sensitive", "data": { "X_25": 2 }, "valid": true }, { "description": "regexes are case sensitive, 2", "data": { "x_25": 3 }, "valid": false } ] } ] ajv-keywords-3.4.1/spec/tests/prohibited.json000066400000000000000000000027771351017536700213110ustar00rootroot00000000000000[ { "description": "prohibited requires that no property in the list is present", "schema": { "prohibited": ["foo"] }, "tests": [ { "description": "no property present is valid", "data": { "baz": 1 }, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true }, { "description": "property is present is invalid", "data": { "foo": 1 }, "valid": false } ] }, { "description": "multiple properties in prohibited", "schema": { "prohibited": ["foo", "bar"] }, "tests": [ { "description": "no property present is valid", "data": { "baz": 1 }, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true }, { "description": "one of properties present is invalid", "data": { "foo": 1 }, "valid": false }, { "description": "both properties present is invalid", "data": { "foo": 1, "bar": 2 }, "valid": false } ] }, { "description": "prohibited with the empty list of properties", "schema": { "prohibited": [] }, "tests": [ { "description": "any object is valid", "data": { "foo": 1 }, "valid": true }, { "description": "empty object is valid", "data": {}, "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/select.json000066400000000000000000000202041351017536700204200ustar00rootroot00000000000000[ { "description": "select keyword", "schema": { "type": "object", "properties": { "type": { "type": "string" } }, "select": { "$data": "0/type" }, "selectCases": { "foo": { "properties": { "type": {}, "foo": { "type": "string" } }, "additionalProperties": false }, "bar": { "properties": { "type": {}, "bar": { "type": "number" } }, "additionalProperties": false } } }, "tests": [ { "description": "valid object, type=foo", "data": { "type": "foo", "foo": "anything" }, "valid": true }, { "description": "valid object, type=bar", "data": { "type": "bar", "bar": 123 }, "valid": true }, { "description": "invalid object, type=foo", "data": { "type": "foo", "foo": 123 }, "valid": false }, { "description": "invalid object, type=bar", "data": { "type": "bar", "bar": "anything" }, "valid": false }, { "description": "invalid object with additional property, type=foo", "data": { "type": "foo", "foo": "anything", "another": 1 }, "valid": false }, { "description": "valid object with unknown type", "data": { "type": "another", "foo": 123 }, "valid": true }, { "description": "valid object without type", "data": { "foo": 123 }, "valid": true } ] }, { "description": "select keyword with selectDefault", "schema": { "type": "object", "properties": { "type": { "type": "string" } }, "select": { "$data": "0/type" }, "selectCases": { "foo": { "properties": { "type": {}, "foo": { "type": "string" } }, "additionalProperties": false }, "bar": { "properties": { "type": {}, "bar": { "type": "number" } }, "additionalProperties": false } }, "selectDefault": { "propertyNames": { "not": { "enum": ["foo", "bar"] } } } }, "tests": [ { "description": "valid object, type=foo", "data": { "type": "foo", "foo": "anything" }, "valid": true }, { "description": "valid object, type=bar", "data": { "type": "bar", "bar": 123 }, "valid": true }, { "description": "invalid object, type=foo", "data": { "type": "foo", "foo": 123 }, "valid": false }, { "description": "invalid object, type=bar", "data": { "type": "bar", "bar": "anything" }, "valid": false }, { "description": "invalid object with additional property, type=foo", "data": { "type": "foo", "foo": "anything", "another": 1 }, "valid": false }, { "description": "valid object with unknown type", "data": { "type": "another", "another": 123 }, "valid": true }, { "description": "invalid object with unknown type", "data": { "type": "another", "foo": "anything" }, "valid": false }, { "description": "valid object without type", "data": { "foo": 123 }, "valid": true } ] }, { "description": "select keyword with fixed selector value", "schema": { "type": "object", "select": "foo", "selectCases": { "foo": { "properties": { "type": { "const": "foo"}, "foo": { "type": "string" } }, "additionalProperties": false }, "bar": { "properties": { "type": { "const": "bar"}, "bar": { "type": "number" } }, "additionalProperties": false } } }, "tests": [ { "description": "valid object, type=foo", "data": { "type": "foo", "foo": "anything" }, "valid": true }, { "description": "invalid object, type=bar", "data": { "type": "bar", "bar": 123 }, "valid": false }, { "description": "invalid object, type=foo", "data": { "type": "foo", "foo": 123 }, "valid": false }, { "description": "invalid object, type=bar", "data": { "type": "bar", "bar": "anything" }, "valid": false }, { "description": "invalid object with additional property, type=foo", "data": { "type": "foo", "foo": "anything", "another": 1 }, "valid": false }, { "description": "invalid object with unknown type", "data": { "type": "another", "foo": 123 }, "valid": false }, { "description": "invalid object without type", "data": { "foo": 123 }, "valid": false } ] }, { "skip": true, "description": "select keyword with relative URIs in $ref (not supported)", "schema": { "type": "object", "definitions": { "num": { "type": "number" }, "str": { "type": "string" } }, "properties": { "type": { "type": "string" } }, "select": { "$data": "0/type" }, "selectCases": { "foo": { "properties": { "type": {}, "foo": { "$ref": "#/definitions/str" } }, "additionalProperties": false }, "bar": { "properties": { "type": {}, "bar": { "$ref": "#/definitions/num" } }, "additionalProperties": false } } }, "tests": [ { "description": "valid object, type=foo", "data": { "type": "foo", "foo": "anything" }, "valid": true }, { "description": "invalid object, type=foo", "data": { "type": "foo", "foo": 123 }, "valid": false } ] }, { "description": "select keyword with absolute URIs in $ref (supported)", "schema": { "$id": "select_test.json", "type": "object", "definitions": { "num": { "type": "number" }, "str": { "type": "string" } }, "properties": { "type": { "type": "string" } }, "select": { "$data": "0/type" }, "selectCases": { "foo": { "properties": { "type": {}, "foo": { "$ref": "select_test.json#/definitions/str" } }, "additionalProperties": false }, "bar": { "properties": { "type": {}, "bar": { "$ref": "select_test.json#/definitions/num" } }, "additionalProperties": false } } }, "tests": [ { "description": "valid object, type=foo", "data": { "type": "foo", "foo": "anything" }, "valid": true }, { "description": "valid object, type=bar", "data": { "type": "bar", "bar": 123 }, "valid": true }, { "description": "invalid object, type=foo", "data": { "type": "foo", "foo": 123 }, "valid": false }, { "description": "invalid object, type=bar", "data": { "type": "bar", "bar": "anything" }, "valid": false } ] } ] ajv-keywords-3.4.1/spec/tests/switch.json000066400000000000000000000130331351017536700204440ustar00rootroot00000000000000[ { "description": "switch keyword validation", "schema": { "switch": [ { "if": { "minimum": 10 }, "then": { "multipleOf": 2 } } ] }, "tests": [ { "description": ">= 10 and even is valid", "data": 12, "valid": true }, { "description": ">= 10 and odd is invalid", "data": 11, "valid": false }, { "description": "< 10 is valid", "data": 9, "valid": true } ] }, { "description": "switch keyword with then clause boolean", "schema": { "switch": [ { "if": { "minimum": 10 }, "then": { "multipleOf": 2 } }, { "if": { "maximum": 4 }, "then": false } ] }, "tests": [ { "description": ">=10 and even is valid", "data": 12, "valid": true }, { "description": ">=10 and odd is invalid", "data": 11, "valid": false }, { "description": "<10 is valid", "data": 7, "valid": true }, { "description": "<4 is invalid", "data": 3, "valid": false } ] }, { "description": "switch keyword with single then clause schema", "schema": { "switch": [ { "if": { "maximum": 10 }, "then": { "multipleOf": 2 } }, { "then": { "multipleOf": 5 } } ] }, "tests": [ { "description": "<=10 and even is valid", "data": 8, "valid": true }, { "description": "<=10 and odd is invalid", "data": 7, "valid": false }, { "description": ">10 and mulitple of 5 is valid", "data": 15, "valid": true }, { "description": ">10 and not mulitple of 5 is invalid", "data": 17, "valid": false } ] }, { "description": "switch keyword with single then clause boolean", "schema": { "description": "positive integer <=1000 with one non-zero digit", "switch": [ { "if": { "not": { "minimum": 1 } }, "then": false }, { "if": { "maximum": 10 }, "then": true }, { "if": { "maximum": 100 }, "then": { "multipleOf": 10 } }, { "if": { "maximum": 1000 }, "then": { "multipleOf": 100 } }, { "then": false } ] }, "tests": [ { "description": "1 is valid", "data": 1, "valid": true }, { "description": "0 is invalid (no positive)", "data": 0, "valid": false }, { "description": "-1 is invalid (negative)", "data": -1, "valid": false }, { "description": "8 is valid", "data": 8, "valid": true }, { "description": "9 is valid", "data": 9, "valid": true }, { "description": "10 is valid", "data": 10, "valid": true }, { "description": "80 is valid", "data": 80, "valid": true }, { "description": "90 is valid", "data": 90, "valid": true }, { "description": "100 is valid", "data": 100, "valid": true }, { "description": "85 is invalid (not multiple of 10)", "data": 85, "valid": false }, { "description": "800 is valid", "data": 800, "valid": true }, { "description": "900 is valid", "data": 900, "valid": true }, { "description": "1000 is valid", "data": 1000, "valid": true }, { "description": "850 is invalid (not multiple of 100)", "data": 850, "valid": false }, { "description": "> 1000 is invalid", "data": 1001, "valid": false } ] }, { "description": "switch keyword with continue clause", "schema": { "switch": [ { "if": { "minimum": 10 }, "then": { "multipleOf": 2 }, "continue": true }, { "if": { "minimum": 20 }, "then": { "multipleOf": 5 } } ] }, "tests": [ { "description": "<10 is valid", "data": 7, "valid": true }, { "description": ">=10, <20 and even is valid", "data": 12, "valid": true }, { "description": ">=10, <20 and odd is invalid", "data": 11, "valid": false }, { "description": ">=20 and multiple of 2 and 5 is valid", "data": 30, "valid": true }, { "description": ">=20 and not multiple of 2 is invalid", "data": 35, "valid": false }, { "description": ">=20 and not multiple of 5 is invalid", "data": 36, "valid": false } ] }, { "description": "switch keyword with id in sibling subschema", "schema": { "id": "http://example.com/base_switch", "switch": [ { "if": { "id": "http://example.com/if", "minimum": 10 }, "then": { "$ref": "#/definitions/def" } } ], "definitions": { "def": { "multipleOf": 2 } } }, "tests": [ { "description": ">= 10 and even is valid", "data": 12, "valid": true }, { "description": ">= 10 and odd is invalid", "data": 11, "valid": false }, { "description": "< 10 is valid", "data": 9, "valid": true } ] } ] ajv-keywords-3.4.1/spec/tests/uniqueItemProperties.json000066400000000000000000000264651351017536700233620ustar00rootroot00000000000000[ { "description": "uniqueItemProperties keyword validation with single property", "schema": { "uniqueItemProperties": ["id"] }, "tests": [ { "description": "with all unique ids", "data": [ { "id": 1 }, { "id": 2 }, { "id": 3 } ], "valid": true }, { "description": "without unique ids", "data": [ { "id": 1 }, { "id": 1 }, { "id": 3 } ], "valid": false }, { "description": "with all unique object-ids", "data": [ { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 2, "date": 1495213151727 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": true }, { "description": "without unique object-ids", "data": [ { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": false }, { "description": "non-array is valid", "data": 1, "valid": true }, { "description": "non-array is valid even for pseudo-arrays", "data": { "0": { "id": 1 }, "1": { "id": 1 }, "length": 2 }, "valid": true }, { "description": "array with one item is valid", "data": [ { "id": 1 } ], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true }, { "description": "array with non-objects is valid", "data": [1, 1], "valid": true } ] }, { "description": "uniqueItemProperties keyword validation with multiple properties", "schema": { "type": "array", "uniqueItemProperties": ["id", "name"] }, "tests": [ { "description": "with all unique ids and names", "data": [ { "id": 1, "name": "taco" }, { "id": 2, "name": "burrito" }, { "id": 3, "name": "salsa" } ], "valid": true }, { "description": "with unique ids but not unique names", "data": [ { "id": 1, "name": "taco" }, { "id": 2, "name": "taco" }, { "id": 3, "name": "salsa" } ], "valid": false } ] }, { "description": "uniqueItemProperties keyword validation with no properties", "schema": { "type": "array", "uniqueItemProperties": [] }, "tests": [ { "description": "with deepEqual like objects", "data": [ { "id": 1 }, { "id": 1 }, { "id": 1 } ], "valid": true } ] }, { "description": "uniqueItemProperties keyword validation with single property of scalar type", "schema": { "uniqueItemProperties": ["id"], "items": { "properties": { "id": {"type": "number"} } } }, "tests": [ { "description": "with all unique ids", "data": [ { "id": 1 }, { "id": 2 }, { "id": 3 } ], "valid": true }, { "description": "without unique ids", "data": [ { "id": 1 }, { "id": 1 }, { "id": 3 } ], "valid": false }, { "description": "with all unique object-ids", "data": [ { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 2, "date": 1495213151727 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": false }, { "description": "without unique object-ids", "data": [ { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": false }, { "description": "non-array is valid", "data": 1, "valid": true }, { "description": "non-array is valid even for pseudo-arrays", "data": { "0": { "id": 1 }, "1": { "id": 1 }, "length": 2 }, "valid": true }, { "description": "array with one item is valid", "data": [ { "id": 1 } ], "valid": true }, { "description": "empty array is valid", "data": [], "valid": true }, { "description": "array with non-objects is valid", "data": [1, 1], "valid": true } ] }, { "description": "uniqueItemProperties keyword validation with single property of non-scalar type", "schema": { "uniqueItemProperties": ["id"], "items": { "properties": { "id": {"type": "object"} } } }, "tests": [ { "description": "with all unique object-ids", "data": [ { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 2, "date": 1495213151727 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": true }, { "description": "without unique object-ids", "data": [ { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": false } ] }, { "description": "uniqueItemProperties keyword validation with single property of multiple scalar types", "schema": { "uniqueItemProperties": ["id"], "items": { "properties": { "id": {"type": ["number", "string"]} } } }, "tests": [ { "description": "with all unique ids", "data": [ { "id": 1 }, { "id": 2 }, { "id": 3 }, { "id": "1" }, { "id": "2" }, { "id": "3" } ], "valid": true }, { "description": "without unique ids", "data": [ { "id": 1 }, { "id": 1 }, { "id": 3 }, { "id": "1" }, { "id": "2" }, { "id": "3" } ], "valid": false } ] }, { "description": "uniqueItemProperties keyword validation with single property of multiple types", "schema": { "uniqueItemProperties": ["id"], "items": { "properties": { "id": {"type": ["number", "object"]} } } }, "tests": [ { "description": "with all unique ids", "data": [ { "id": 1 }, { "id": 2 }, { "id": 3 }, { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 2, "date": 1495213151727 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": true }, { "description": "without unique ids", "data": [ { "id": 1 }, { "id": 2 }, { "id": 3 }, { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 1, "date": 1495213151726 } }, { "id": { "_id": 3, "date": 1495213151728 } } ], "valid": false } ] }, { "description": "uniqueItemProperties keyword validation with multiple properties", "schema": { "type": "array", "uniqueItemProperties": ["id", "name"] }, "tests": [ { "description": "with all unique ids and names", "data": [ { "id": 1, "name": "taco" }, { "id": 2, "name": "burrito" }, { "id": 3, "name": "salsa" } ], "valid": true }, { "description": "with unique ids but not unique names", "data": [ { "id": 1, "name": "taco" }, { "id": 2, "name": "taco" }, { "id": 3, "name": "salsa" } ], "valid": false } ] }, { "description": "uniqueItemProperties keyword validation with multiple properties of scalar types", "schema": { "type": "array", "uniqueItemProperties": ["id", "name"], "items": { "properties": { "id": {"type": "number"}, "name": {"type": "string"} } } }, "tests": [ { "description": "with all unique ids and names", "data": [ { "id": 1, "name": "taco" }, { "id": 2, "name": "burrito" }, { "id": 3, "name": "salsa" } ], "valid": true }, { "description": "with unique ids but not unique names", "data": [ { "id": 1, "name": "taco" }, { "id": 2, "name": "taco" }, { "id": 3, "name": "salsa" } ], "valid": false } ] }, { "description": "uniqueItemProperties keyword validation with multiple properties with some scalar types", "schema": { "type": "array", "uniqueItemProperties": ["id", "name"], "items": { "properties": { "id": {"type": "object"}, "name": {"type": "string"} } } }, "tests": [ { "description": "with all unique ids and names", "data": [ { "id": { "_id": 1, "date": 1495213151726 }, "name": "taco" }, { "id": { "_id": 2, "date": 1495213151727 }, "name": "burrito" }, { "id": { "_id": 3, "date": 1495213151728 }, "name": "salsa" } ], "valid": true }, { "description": "with non-unique ids but unique names", "data": [ { "id": { "_id": 1, "date": 1495213151726 }, "name": "taco" }, { "id": { "_id": 1, "date": 1495213151726 }, "name": "burrito" }, { "id": { "_id": 3, "date": 1495213151727 }, "name": "salsa" } ], "valid": false } ] }, { "description": "uniqueItemProperties keyword with null item(s)", "schema": { "type": "array", "uniqueItemProperties": ["id"], "items": { "properties": { "id": {"type": "integer"} } } }, "tests": [ { "description": "with all unique ids and null items is valid", "data": [ { "id": 1 }, { "id": 2 }, null, null ], "valid": true }, { "description": "with non-unique ids and null item is invalid", "data": [ { "id": 1 }, { "id": 1 }, null, null ], "valid": false } ] }, { "description": "uniqueItemProperties keyword with null item(s) and object keys", "schema": { "type": "array", "uniqueItemProperties": ["id"], "items": { "properties": { "id": {"type": "object"} } } }, "tests": [ { "description": "with all unique ids and null items is valid", "data": [ { "id": {"_id": 1} }, { "id": {"_id": 2} }, null, null ], "valid": true }, { "description": "with non-unique ids and null item is invalid", "data": [ { "id": {"_id": 1} }, { "id": {"_id": 1} }, null, null ], "valid": false } ] } ] ajv-keywords-3.4.1/spec/transform.spec.js000066400000000000000000000111371351017536700204130ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var defFunc = require('../keywords/transform'); var defineKeywords = require('..'); require('chai').should(); describe('keyword "transform"', function () { var ajvs = [ defFunc(new Ajv), defineKeywords(new Ajv, 'transform'), defineKeywords(new Ajv) ]; ajvs.forEach(function (ajv, i) { it('should transform by wrapper #' + i, function () { var schema, data; data = {o: ' Object '}; schema = {type: 'object', properties: {o: {type: 'string', transform: ['trim', 'toLowerCase']}}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal({o:'object'}); data = [' Array ']; schema = {type: 'array', items: {type: 'string', transform: ['trim','toUpperCase']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['ARRAY']); data = ' String '; schema = {type: 'string', transform: ['trim', 'toLowerCase']}; ajv.validate(schema, data) .should.equal(true); // Note: Doesn't work on plain strings due to object being undefined data.should.equal(' String '); }); }); ajvs.forEach(function (ajv, i) { it('should not transform non-strings #' + i, function () { var schema, data; data = ['a', 1, null, [], {}]; schema = {type: 'array', items: {type: 'string', transform: ['toUpperCase']}}; ajv.validate(schema, data) .should.equal(false); data.should.deep.equal(['A', 1, null, [], {}]); }); }); ajvs.forEach(function (ajv, i) { it('should transform trim #' + i, function () { var schema, data; data = [' trimObject ']; schema = {type: 'array', items: {type: 'string', transform: ['trimLeft']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['trimObject ']); data = [' trimObject ']; schema = {type: 'array', items: {type: 'string', transform: ['trimRight']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal([' trimObject']); data = [' trimObject ']; schema = {type: 'array', items: {type: 'string', transform: ['trimLeft','trimRight']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['trimObject']); data = [' trimObject ']; schema = {type: 'array', items: {type: 'string', transform: ['trim']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['trimObject']); }); }); ajvs.forEach(function (ajv, i) { it('should transform text case #' + i, function () { var schema, data; data = ['MixCase']; schema = {type: 'array', items: {type: 'string', transform: ['toLowerCase']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['mixcase']); data = ['MixCase']; schema = {type: 'array', items: {type: 'string', transform: ['toUpperCase']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['MIXCASE']); data = ['ph', 'PH','pH','Ph']; schema = {type: 'array', items: {type: 'string', transform: ['toEnumCase'], enum:['pH']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['pH','pH','pH','pH']); data = ['ph', 'PH','pH','Ph', 7]; schema = {type: 'array', items: {type: ['string','integer'], transform: ['toEnumCase'], enum:['pH', 7]}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['pH','pH','pH','pH', 7]); data = ['ph']; schema = {type: 'array', items: {type: 'string', transform: ['toEnumCase']}}; try { ajv.validate(schema, data).should.equal(false); } catch (e) { e.message.should.equal('Missing enum. To use `transform:["toEnumCase"]`, `enum:[...]` is required.'); } data = ['ph']; schema = {type: 'array', items: {type: 'string', transform: ['toEnumCase'], enum:['pH','PH']}}; try { ajv.validate(schema, data).should.equal(false); } catch (e) { e.message.should.equal('Invalid enum uniqueness. To use `transform:["toEnumCase"]`, all values must be unique when case insensitive.'); } data = [' ph ']; schema = {type: 'array', items: {type: 'string', transform: ['trim', 'toEnumCase'], enum:['pH']}}; ajv.validate(schema, data) .should.equal(true); data.should.deep.equal(['pH']); data = ['ab']; schema = {type: 'array', items: {type: 'string', transform: ['toEnumCase'], enum:['pH']}}; ajv.validate(schema, data) .should.equal(false); data.should.deep.equal(['ab']); }); }); }); ajv-keywords-3.4.1/spec/typeof.spec.js000066400000000000000000000037061351017536700177110ustar00rootroot00000000000000'use strict'; var Ajv = require('ajv'); var ajvPack = require('ajv-pack'); var defFunc = require('../keywords/typeof'); var defineKeywords = require('..'); var should = require('chai').should(); describe('keyword "typeof"', function() { var ajvs = [ defFunc(new Ajv), defineKeywords(new Ajv, 'typeof'), defineKeywords(new Ajv), defFunc(ajvPack.instance(new Ajv({sourceCode: true}))) ]; ajvs.forEach(function (ajv, i) { it('should validate value types #' + i, function() { ajv.validate({ typeof: 'undefined' }, undefined) .should.equal(true); ajv.validate({ typeof: 'undefined' }, null) .should.equal(false); ajv.validate({ typeof: 'undefined' }, 'foo') .should.equal(false); ajv.validate({ typeof: 'function' }, function(){}) .should.equal(true); ajv.validate({ typeof: 'function' }, {}) .should.equal(false); ajv.validate({ typeof: 'object' }, {}) .should.equal(true); ajv.validate({ typeof: 'object' }, null) .should.equal(true); ajv.validate({ typeof: 'object' }, 'foo') .should.equal(false); ajv.validate({ typeof: 'symbol' }, Symbol()) .should.equal(true); ajv.validate({ typeof: 'symbol' }, {}) .should.equal(false); }); it('should validate multiple types #' + i, function() { ajv.validate({ typeof: ['string', 'function'] }, 'foo') .should.equal(true); ajv.validate({ typeof: ['string', 'function'] }, function(){}) .should.equal(true); ajv.validate({ typeof: ['string', 'function'] }, {}) .should.equal(false); }); it('should throw when unknown type is passed #' + i, function() { should.throw(function() { ajv.compile({ typeof: 'unknownType' }); }); should.throw(function() { ajv.compile({ typeof: ['string', 'unknownType'] }); }); }); it('should throw when not string or array is passed #' + i, function() { should.throw(function() { ajv.compile({ typeof: 1 }); }); }); }); });