refactor: contains implemented as a standard keyword, #367

master
Evgeny Poberezkin 2016-12-30 17:44:18 +00:00
parent cf3f1cea50
commit 41ecdaff7c
10 changed files with 69 additions and 13 deletions

View File

@ -70,13 +70,6 @@ function Ajv(opts) {
this._compilations = [];
this.RULES = rules();
this.addKeyword('contains', {
type: 'array',
macro: function (schema) {
return { not: { items: { not: schema } } };
}
});
opts.loopRequired = opts.loopRequired || Infinity;
if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true;
this._metaOpts = getMetaSchemaOptions(this);

View File

@ -6,6 +6,7 @@ module.exports = {
allOf: require('../dotjs/allOf'),
anyOf: require('../dotjs/anyOf'),
const: require('../dotjs/const'),
contains: require('../dotjs/contains'),
dependencies: require('../dotjs/dependencies'),
'enum': require('../dotjs/enum'),
format: require('../dotjs/format'),

View File

@ -112,7 +112,7 @@ function compile(schema, root, localRefs, baseId) {
+ sourceCode;
if (opts.processCode) sourceCode = opts.processCode(sourceCode);
// console.log('\n\n\n *** \n', sourceCode);
// console.log('\n\n\n *** \n', JSON.stringify(sourceCode));
var validate;
try {
var makeValidate = new Function(

View File

@ -11,7 +11,7 @@ module.exports = function rules() {
{ type: 'string',
rules: [ 'maxLength', 'minLength', 'pattern', 'format' ] },
{ type: 'array',
rules: [ 'maxItems', 'minItems', 'uniqueItems', 'items' ] },
rules: [ 'maxItems', 'minItems', 'uniqueItems', 'contains', 'items' ] },
{ type: 'object',
rules: [ 'maxProperties', 'minProperties', 'required', 'dependencies', 'propertyNames',
{ 'properties': ['additionalProperties', 'patternProperties'] } ] },

55
lib/dot/contains.jst Normal file
View File

@ -0,0 +1,55 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{
var $idx = 'i' + $lvl
, $dataNxt = $it.dataLevel = it.dataLevel + 1
, $nextData = 'data' + $dataNxt
, $currentBaseId = it.baseId
, $nonEmptySchema = {{# def.nonEmptySchema:$schema }};
}}
var {{=$errs}} = errors;
var {{=$valid}};
{{? $nonEmptySchema }}
{{# def.setCompositeRule }}
{{
$it.schema = $schema;
$it.schemaPath = $schemaPath;
$it.errSchemaPath = $errSchemaPath;
}}
for (var {{=$idx}} = 0; {{=$idx}} < {{=$data}}.length; {{=$idx}}++) {
{{
$it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true);
var $passData = $data + '[' + $idx + ']';
$it.dataPathArr[$dataNxt] = $idx;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
if ({{=$nextValid}}) break;
}
{{# def.resetCompositeRule }}
{{= $closingBraces }}
if (!{{=$nextValid}}) {
{{??}}
if ({{=$data}}.length == 0) {
{{?}}
{{# def.error:'contains' }}
} else {
{{? $nonEmptySchema }}
{{# def.resetErrors }}
{{?}}
{{? it.opts.allErrors }} } {{?}}
{{# def.cleanUp }}

View File

@ -97,6 +97,7 @@
additionalProperties: "'should NOT have additional properties'",
anyOf: "'should match some schema in anyOf'",
const: "'should be equal to constant'",
contains: "'should contain a valid item'",
dependencies: "'should have {{? $deps.length == 1 }}property {{= it.util.escapeQuotes($deps[0]) }}{{??}}properties {{= it.util.escapeQuotes($deps.join(\", \")) }}{{?}} when property {{= it.util.escapeQuotes($property) }} is present'",
'enum': "'should be equal to one of the allowed values'",
format: "'should match format \"{{#def.concatSchemaEQ}}\"'",
@ -132,6 +133,7 @@
additionalProperties: "false",
anyOf: "validate.schema{{=$schemaPath}}",
const: "validate.schema{{=$schemaPath}}",
contains: "validate.schema{{=$schemaPath}}",
dependencies: "validate.schema{{=$schemaPath}}",
'enum': "validate.schema{{=$schemaPath}}",
format: "{{#def.schemaRefOrQS}}",
@ -166,6 +168,7 @@
additionalProperties: "{ additionalProperty: '{{=$additionalProperty}}' }",
anyOf: "{}",
const: "{}",
constains: "{}",
dependencies: "{ property: '{{= it.util.escapeQuotes($property) }}', missingProperty: '{{=$missingProperty}}', depsCount: {{=$deps.length}}, deps: '{{= it.util.escapeQuotes($deps.length==1 ? $deps[0] : $deps.join(\", \")) }}' }",
'enum': "{ allowedValues: schema{{=$lvl}} }",
format: "{ format: {{#def.schemaValueQS}} }",

View File

@ -90,7 +90,6 @@ var {{=$valid}};
$it.errSchemaPath = $errSchemaPath;
}}
{{# def.validateItems: 0 }}
{{# def.ifResultValid }}
{{?}}
{{? $breakOnError }}

View File

@ -230,7 +230,7 @@
{{# def.cleanUp }}
{{? $top && $breakOnError }}
{{? $top }}
{{# def.finalCleanUp }}
{{?}}

View File

@ -259,13 +259,13 @@ describe('boolean schemas', function() {
describe('in contains', function() {
describe('schema = true', function() {
it('should be valid with any property', function() {
it('should be valid with any items', function() {
ajvs.forEach(test(true, true));
});
});
describe('schema = false', function() {
it('should be invalid with any property', function() {
it('should be invalid with any items', function() {
ajvs.forEach(test(false, false));
});
});

View File

@ -20,6 +20,11 @@
"data": [1, 2, 3, 4],
"valid": false
},
{
"description": "empty array is invalid",
"data": [],
"valid": false
},
{
"description": "not array is valid",
"data": {},