Skip to content

Commit

Permalink
feat: allRequired keyword, closes #79
Browse files Browse the repository at this point in the history
  • Loading branch information
epoberezkin committed Feb 9, 2019
1 parent 16a5695 commit 87a637f
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 4 deletions.
31 changes: 31 additions & 0 deletions README.md
Expand Up @@ -27,6 +27,7 @@ Custom JSON-Schema keywords for [Ajv](https://github.com/epoberezkin/ajv) valida
- [Keywords for arrays](#keywords-for-arrays)
- [uniqueItemProperties](#uniqueitemproperties)
- [Keywords for objects](#keywords-for-objects)
- [allRequired](allrequired)
- [patternRequired](#patternrequired)
- [prohibited](#prohibited)
- [deepProperties](#deepproperties)
Expand Down Expand Up @@ -307,6 +308,36 @@ 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 properties keyword is not used in the same schema object, 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).

```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 } ];
```


#### `patternRequired`

This keyword allows to require the presence of properties that match some pattern(s).
Expand Down
19 changes: 19 additions & 0 deletions keywords/allRequired.js
@@ -0,0 +1,19 @@
'use strict';

module.exports = function defFunc(ajv) {
defFunc.definition = {
type: 'object',
macro: function (schema, parentSchema) {
if (!schema) return {};
var properties = Object.keys(parentSchema.properties || {});
if (properties.length == 0) return {};
return { required: properties };
},
metaSchema: {
type: 'boolean'
}
};

ajv.addKeyword('allRequired', defFunc.definition);
return ajv;
};
1 change: 1 addition & 0 deletions keywords/index.js
Expand Up @@ -6,6 +6,7 @@ module.exports = {
regexp: require('./regexp'),
'typeof': require('./typeof'),
dynamicDefaults: require('./dynamicDefaults'),
allRequired: require('./allRequired'),
prohibited: require('./prohibited'),
uniqueItemProperties: require('./uniqueItemProperties'),
deepProperties: require('./deepProperties'),
Expand Down
1 change: 0 additions & 1 deletion keywords/prohibited.js
Expand Up @@ -22,4 +22,3 @@ module.exports = function defFunc(ajv) {
ajv.addKeyword('prohibited', defFunc.definition);
return ajv;
};

15 changes: 12 additions & 3 deletions spec/schema-tests.spec.js
Expand Up @@ -5,9 +5,18 @@ var jsonSchemaTest = require('json-schema-test');
var defineKeywords = require('..');

var ajvs = [
defineKeywords(getAjv(),
['switch', 'patternRequired', 'formatMinimum', 'formatMaximum',
'uniqueItemProperties', 'prohibited', 'deepRequired', 'deepProperties', 'select']),
defineKeywords(getAjv(), [
'allRequired',
'deepProperties',
'deepRequired',
'formatMaximum',
'formatMinimum',
'patternRequired',
'prohibited',
'select',
'switch',
'uniqueItemProperties'
]),
defineKeywords(getAjv()),
defineKeywords(getAjv(true)),
defineKeywords(getAjvNoMeta())
Expand Down
104 changes: 104 additions & 0 deletions spec/tests/allRequired.json
@@ -0,0 +1,104 @@
[
{
"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
}
]
},
{
"description": "allRequired passed validation if properties keyword is absent",
"schema": {
"allRequired": true
},
"tests": [
{
"description": "any object is valid",
"data": {"foo": 1, "bar": 2},
"valid": true
},
{
"description": "empty object is valid",
"data": {},
"valid": true
}
]
}
]

0 comments on commit 87a637f

Please sign in to comment.