Allow custom keywords that are not valid JS identifiers
Custom keywords were required to be valid JS identifiers due to the way they were being used in the generated code. This prevented the use of keywords with the `x-` prefix that is required by [swagger](http://swagger.io]. This change fixes that by updating the only place that was using them directly as an identifier to use //brackets// notation rather than //dot// notation. This brings the definition of `$schemaPath` in `definitions.def` in line with the way the rule definition is accessed from `RULES.custom` at the top of `custom.jst`. The validation of the keyword name has been changed to allow any name in this change, but this should be updated to either just remove the test or update it to a new rule before this change is included in the project. Finally, this also updates a number of the tests in `custom.spec.js` to use non-valid identifiers for the names of some of the custom keywords being tested (primarily by adding `x-` to the front of the name). Test Plan: - Run `npm test` and ensure all tests run and passmaster
parent
7613986c29
commit
66db560ca5
|
@ -3,7 +3,7 @@
|
|||
var $lvl = it.level;
|
||||
var $dataLvl = it.dataLevel;
|
||||
var $schema = it.schema[$keyword];
|
||||
var $schemaPath = it.schemaPath + '.' + $keyword;
|
||||
var $schemaPath = it.schemaPath + '[\'' + $keyword + '\']';
|
||||
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
|
||||
var $breakOnError = !it.opts.allErrors;
|
||||
var $errorKeyword;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
var IDENTIFIER = /^[a-z_$][a-z0-9_$]*$/i;
|
||||
var IDENTIFIER = /^.*$/i;
|
||||
var customRuleCode = require('./dotjs/custom');
|
||||
|
||||
module.exports = {
|
||||
|
|
|
@ -37,7 +37,7 @@ describe('Custom keywords', function () {
|
|||
metaSchema: { "type": "boolean" }
|
||||
});
|
||||
|
||||
shouldBeInvalidSchema({ "even": "not_boolean" });
|
||||
shouldBeInvalidSchema({ "x-even": "not_boolean" });
|
||||
|
||||
function validateEven(schema, data) {
|
||||
return data % 2 ? !schema : schema;
|
||||
|
@ -69,9 +69,9 @@ describe('Custom keywords', function () {
|
|||
"additionalItems": false
|
||||
}
|
||||
});
|
||||
shouldBeInvalidSchema({ range: [ "1", 2 ] });
|
||||
shouldBeInvalidSchema({ range: {} });
|
||||
shouldBeInvalidSchema({ range: [ 1, 2, 3 ] });
|
||||
shouldBeInvalidSchema({ 'x-range': [ "1", 2 ] });
|
||||
shouldBeInvalidSchema({ 'x-range': {} });
|
||||
shouldBeInvalidSchema({ 'x-range': [ 1, 2, 3 ] });
|
||||
|
||||
function validateRange(schema, data, parentSchema) {
|
||||
return parentSchema.exclusiveRange === true
|
||||
|
@ -94,7 +94,7 @@ describe('Custom keywords', function () {
|
|||
var valid = minOk && maxOk;
|
||||
|
||||
if (!valid) {
|
||||
var err = { keyword: 'range' };
|
||||
var err = { keyword: 'x-range' };
|
||||
validateRange.errors = [err];
|
||||
var comparison, limit;
|
||||
if (minOk) {
|
||||
|
@ -121,7 +121,7 @@ describe('Custom keywords', function () {
|
|||
describe('rule with "compiled" keyword validation', function() {
|
||||
it('should add and validate rule', function() {
|
||||
testEvenKeyword({ type: 'number', compile: compileEven });
|
||||
shouldBeInvalidSchema({ "even": "not_boolean" });
|
||||
shouldBeInvalidSchema({ "x-even": "not_boolean" });
|
||||
|
||||
function compileEven(schema) {
|
||||
if (typeof schema != 'boolean') throw new Error('The value of "even" keyword must be boolean');
|
||||
|
@ -138,7 +138,7 @@ describe('Custom keywords', function () {
|
|||
compile: compileEven,
|
||||
metaSchema: { "type": "boolean" }
|
||||
});
|
||||
shouldBeInvalidSchema({ "even": "not_boolean" });
|
||||
shouldBeInvalidSchema({ "x-even": "not_boolean" });
|
||||
|
||||
function compileEven(schema) {
|
||||
return schema ? isEven : isOdd;
|
||||
|
@ -565,7 +565,7 @@ describe('Custom keywords', function () {
|
|||
metaSchema: { "type": "boolean" }
|
||||
});
|
||||
compileCalled .should.equal(true);
|
||||
shouldBeInvalidSchema({ "even": "false" });
|
||||
shouldBeInvalidSchema({ "x-even-$data": "false" });
|
||||
|
||||
function validateEven(schema, data) {
|
||||
return data % 2 ? !schema : schema;
|
||||
|
@ -613,7 +613,7 @@ describe('Custom keywords', function () {
|
|||
metaSchema: { "type": "boolean" }
|
||||
}, 2);
|
||||
macroCalled .should.equal(true);
|
||||
shouldBeInvalidSchema({ "even": "false" });
|
||||
shouldBeInvalidSchema({ "x-even-$data": "false" });
|
||||
|
||||
function validateEven(schema, data) {
|
||||
return data % 2 ? !schema : schema;
|
||||
|
@ -658,7 +658,7 @@ describe('Custom keywords', function () {
|
|||
metaSchema: { "type": "boolean" }
|
||||
});
|
||||
inlineCalled .should.equal(true);
|
||||
shouldBeInvalidSchema({ "even": "false" });
|
||||
shouldBeInvalidSchema({ "x-even-$data": "false" });
|
||||
|
||||
function validateEven(schema, data) {
|
||||
return data % 2 ? !schema : schema;
|
||||
|
@ -685,8 +685,8 @@ describe('Custom keywords', function () {
|
|||
|
||||
function testEvenKeyword(definition, numErrors) {
|
||||
instances.forEach(function (_ajv) {
|
||||
_ajv.addKeyword('even', definition);
|
||||
var schema = { "even": true };
|
||||
_ajv.addKeyword('x-even', definition);
|
||||
var schema = { "x-even": true };
|
||||
var validate = _ajv.compile(schema);
|
||||
|
||||
shouldBeValid(validate, 2);
|
||||
|
@ -698,9 +698,9 @@ describe('Custom keywords', function () {
|
|||
|
||||
function testEvenKeyword$data(definition, numErrors) {
|
||||
instances.forEach(function (_ajv) {
|
||||
_ajv.addKeyword('even', definition);
|
||||
_ajv.addKeyword('x-even-$data', definition);
|
||||
|
||||
var schema = { "even": true };
|
||||
var schema = { "x-even-$data": true };
|
||||
var validate = _ajv.compile(schema);
|
||||
|
||||
shouldBeValid(validate, 2);
|
||||
|
@ -710,7 +710,7 @@ describe('Custom keywords', function () {
|
|||
|
||||
schema = {
|
||||
"properties": {
|
||||
"data": { "even": { "$data": "1/evenValue" } },
|
||||
"data": { "x-even-$data": { "$data": "1/evenValue" } },
|
||||
"evenValue": {}
|
||||
}
|
||||
};
|
||||
|
@ -744,15 +744,15 @@ describe('Custom keywords', function () {
|
|||
|
||||
function testMultipleConstantKeyword(definition, numErrors) {
|
||||
instances.forEach(function (_ajv) {
|
||||
_ajv.addKeyword('constant', definition);
|
||||
_ajv.addKeyword('x-constant', definition);
|
||||
|
||||
var schema = {
|
||||
"properties": {
|
||||
"a": { "constant": 1 },
|
||||
"b": { "constant": 1 }
|
||||
"a": { "x-constant": 1 },
|
||||
"b": { "x-constant": 1 }
|
||||
},
|
||||
"additionalProperties": { "constant": { "foo": "bar" } },
|
||||
"items": { "constant": { "foo": "bar" } }
|
||||
"additionalProperties": { "x-constant": { "foo": "bar" } },
|
||||
"items": { "x-constant": { "foo": "bar" } }
|
||||
};
|
||||
var validate = _ajv.compile(schema);
|
||||
|
||||
|
@ -771,9 +771,9 @@ describe('Custom keywords', function () {
|
|||
|
||||
function testRangeKeyword(definition, customErrors, numErrors) {
|
||||
instances.forEach(function (_ajv) {
|
||||
_ajv.addKeyword('range', definition);
|
||||
_ajv.addKeyword('x-range', definition);
|
||||
|
||||
var schema = { "range": [2, 4] };
|
||||
var schema = { "x-range": [2, 4] };
|
||||
var validate = _ajv.compile(schema);
|
||||
|
||||
shouldBeValid(validate, 2);
|
||||
|
@ -782,14 +782,14 @@ describe('Custom keywords', function () {
|
|||
shouldBeValid(validate, 'abc');
|
||||
|
||||
shouldBeInvalid(validate, 1.99, numErrors);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '', '#/range', '>=', 2);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '', '#/x-range', '>=', 2);
|
||||
shouldBeInvalid(validate, 4.01, numErrors);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '', '#/range','<=', 4);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '', '#/x-range','<=', 4);
|
||||
|
||||
schema = {
|
||||
"properties": {
|
||||
"foo": {
|
||||
"range": [2, 4],
|
||||
"x-range": [2, 4],
|
||||
"exclusiveRange": true
|
||||
}
|
||||
}
|
||||
|
@ -801,23 +801,23 @@ describe('Custom keywords', function () {
|
|||
shouldBeValid(validate, { foo: 3.99 });
|
||||
|
||||
shouldBeInvalid(validate, { foo: 2 }, numErrors);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '.foo', '#/properties/foo/range', '>', 2, true);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '.foo', '#/properties/foo/x-range', '>', 2, true);
|
||||
shouldBeInvalid(validate, { foo: 4 }, numErrors);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '.foo', '#/properties/foo/range', '<', 4, true);
|
||||
if (customErrors) shouldBeRangeError(validate.errors[0], '.foo', '#/properties/foo/x-range', '<', 4, true);
|
||||
});
|
||||
}
|
||||
|
||||
function testMultipleRangeKeyword(definition, numErrors) {
|
||||
instances.forEach(function (_ajv) {
|
||||
_ajv.addKeyword('range', definition);
|
||||
_ajv.addKeyword('x-range', definition);
|
||||
|
||||
var schema = {
|
||||
"properties": {
|
||||
"a": { "range": [2, 4], "exclusiveRange": true },
|
||||
"b": { "range": [2, 4], "exclusiveRange": false }
|
||||
"a": { "x-range": [2, 4], "exclusiveRange": true },
|
||||
"b": { "x-range": [2, 4], "exclusiveRange": false }
|
||||
},
|
||||
"additionalProperties": { "range": [5, 7] },
|
||||
"items": { "range": [5, 7] }
|
||||
"additionalProperties": { "x-range": [5, 7] },
|
||||
"items": { "x-range": [5, 7] }
|
||||
};
|
||||
var validate = _ajv.compile(schema);
|
||||
|
||||
|
@ -836,7 +836,7 @@ describe('Custom keywords', function () {
|
|||
delete error.schema;
|
||||
delete error.data;
|
||||
error .should.eql({
|
||||
keyword: 'range',
|
||||
keyword: 'x-range',
|
||||
dataPath: dataPath,
|
||||
schemaPath: schemaPath,
|
||||
message: 'should be ' + comparison + ' ' + limit,
|
||||
|
@ -906,14 +906,14 @@ describe('Custom keywords', function () {
|
|||
}
|
||||
});
|
||||
|
||||
it('should throw if keyword is not a valid identifier', function() {
|
||||
it('should not throw even if keyword is not a valid identifier', function() {
|
||||
should.not.throw(function() {
|
||||
ajv.addKeyword('mykeyword', {
|
||||
validate: function() { return true; }
|
||||
});
|
||||
});
|
||||
|
||||
should.throw(function() {
|
||||
should.not.throw(function() {
|
||||
ajv.addKeyword('my-keyword', {
|
||||
validate: function() { return true; }
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{
|
||||
var $data = 'data' + (it.dataLevel || '')
|
||||
, $min = it.schema.range[0]
|
||||
, $max = it.schema.range[1]
|
||||
, $min = it.schema['x-range'][0]
|
||||
, $max = it.schema['x-range'][1]
|
||||
, $gt = it.schema.exclusiveRange ? '>' : '>='
|
||||
, $lt = it.schema.exclusiveRange ? '<' : '<=';
|
||||
}}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{
|
||||
var $data = 'data' + (it.dataLevel || '')
|
||||
, $min = it.schema.range[0]
|
||||
, $max = it.schema.range[1]
|
||||
, $min = it.schema['x-range'][0]
|
||||
, $max = it.schema['x-range'][1]
|
||||
, $exclusive = !!it.schema.exclusiveRange
|
||||
, $gt = $exclusive ? '>' : '>='
|
||||
, $lt = $exclusive ? '<' : '<='
|
||||
|
@ -16,7 +16,7 @@ if (!valid{{=$lvl}}) {
|
|||
var {{=$err}};
|
||||
if (minOk{{=$lvl}}) {
|
||||
{{=$err}} = {
|
||||
keyword: 'range',
|
||||
keyword: 'x-range',
|
||||
message: 'should be {{=$lt}} {{=$max}}',
|
||||
params: {
|
||||
comparison: '{{=$lt}}',
|
||||
|
@ -26,7 +26,7 @@ if (!valid{{=$lvl}}) {
|
|||
};
|
||||
} else {
|
||||
{{=$err}} = {
|
||||
keyword: 'range',
|
||||
keyword: 'x-range',
|
||||
message: 'should be {{=$gt}} {{=$min}}',
|
||||
params: {
|
||||
comparison: '{{=$gt}}',
|
||||
|
|
Loading…
Reference in New Issue