refactor: split issues.spec.js file
parent
71dc5dc27d
commit
a7f78f2894
|
@ -1,815 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('./ajv')
|
||||
, should = require('./chai').should();
|
||||
|
||||
|
||||
describe('issue #8: schema with shared references', function() {
|
||||
it('should be supported by addSchema', spec('addSchema'));
|
||||
|
||||
it('should be supported by compile', spec('compile'));
|
||||
|
||||
function spec(method) {
|
||||
return function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
var propertySchema = {
|
||||
type: 'string',
|
||||
maxLength: 4
|
||||
};
|
||||
|
||||
var schema = {
|
||||
$id: 'obj.json#',
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: propertySchema,
|
||||
bar: propertySchema
|
||||
}
|
||||
};
|
||||
|
||||
ajv[method](schema);
|
||||
|
||||
var result = ajv.validate('obj.json#', { foo: 'abc', bar: 'def' });
|
||||
result .should.equal(true);
|
||||
|
||||
result = ajv.validate('obj.json#', { foo: 'abcde', bar: 'fghg' });
|
||||
result .should.equal(false);
|
||||
ajv.errors .should.have.length(1);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
describe('issue #50: references with "definitions"', function () {
|
||||
it('should be supported by addSchema', spec('addSchema'));
|
||||
|
||||
it('should be supported by compile', spec('addSchema'));
|
||||
|
||||
function spec(method) {
|
||||
return function() {
|
||||
var result;
|
||||
|
||||
var ajv = new Ajv;
|
||||
|
||||
ajv[method]({
|
||||
$id: 'http://example.com/test/person.json#',
|
||||
definitions: {
|
||||
name: { type: 'string' }
|
||||
},
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { $ref: '#/definitions/name'}
|
||||
}
|
||||
});
|
||||
|
||||
ajv[method]({
|
||||
$id: 'http://example.com/test/employee.json#',
|
||||
type: 'object',
|
||||
properties: {
|
||||
person: { $ref: '/test/person.json#' },
|
||||
role: { type: 'string' }
|
||||
}
|
||||
});
|
||||
|
||||
result = ajv.validate('http://example.com/test/employee.json#', {
|
||||
person: {
|
||||
name: 'Alice'
|
||||
},
|
||||
role: 'Programmer'
|
||||
});
|
||||
|
||||
result. should.equal(true);
|
||||
should.equal(ajv.errors, null);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
describe('issue #182, NaN validation', function() {
|
||||
it('should not pass minimum/maximum validation', function() {
|
||||
testNaN({ minimum: 1 }, false);
|
||||
testNaN({ maximum: 1 }, false);
|
||||
});
|
||||
|
||||
it('should pass type: number validation', function() {
|
||||
testNaN({ type: 'number' }, true);
|
||||
});
|
||||
|
||||
it('should not pass type: integer validation', function() {
|
||||
testNaN({ type: 'integer' }, false);
|
||||
});
|
||||
|
||||
function testNaN(schema, NaNisValid) {
|
||||
var ajv = new Ajv;
|
||||
var validate = ajv.compile(schema);
|
||||
validate(NaN) .should.equal(NaNisValid);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
describe('issue #204, options schemas and $data used together', function() {
|
||||
it('should use v5 metaschemas by default', function() {
|
||||
var ajv = new Ajv({
|
||||
schemas: [{$id: 'str', type: 'string'}],
|
||||
$data: true
|
||||
});
|
||||
|
||||
var schema = { const: 42 };
|
||||
var validate = ajv.compile(schema);
|
||||
|
||||
validate(42) .should.equal(true);
|
||||
validate(43) .should.equal(false);
|
||||
|
||||
ajv.validate('str', 'foo') .should.equal(true);
|
||||
ajv.validate('str', 42) .should.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #181, custom keyword is not validated in allErrors mode if there were previous error', function() {
|
||||
it('should validate custom keyword that doesn\'t create errors', function() {
|
||||
testCustomKeywordErrors({
|
||||
type:'object',
|
||||
errors: true,
|
||||
validate: function v(/* value */) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should validate custom keyword that creates errors', function() {
|
||||
testCustomKeywordErrors({
|
||||
type:'object',
|
||||
errors: true,
|
||||
validate: function v(/* value */) {
|
||||
v.errors = v.errors || [];
|
||||
v.errors.push({
|
||||
keyword: 'alwaysFails',
|
||||
message: 'alwaysFails error',
|
||||
params: {
|
||||
keyword: 'alwaysFails'
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function testCustomKeywordErrors(def) {
|
||||
var ajv = new Ajv({ allErrors: true });
|
||||
|
||||
ajv.addKeyword('alwaysFails', def);
|
||||
|
||||
var schema = {
|
||||
required: ['foo'],
|
||||
alwaysFails: true
|
||||
};
|
||||
|
||||
var validate = ajv.compile(schema);
|
||||
|
||||
validate({ foo: 1 }) .should.equal(false);
|
||||
validate.errors .should.have.length(1);
|
||||
validate.errors[0].keyword .should.equal('alwaysFails');
|
||||
|
||||
validate({}) .should.equal(false);
|
||||
validate.errors .should.have.length(2);
|
||||
validate.errors[0].keyword .should.equal('required');
|
||||
validate.errors[1].keyword .should.equal('alwaysFails');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
describe('issue #210, mutual recursive $refs that are schema fragments', function() {
|
||||
it('should compile and validate schema when one ref is fragment', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "foo",
|
||||
"definitions": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"baz": {
|
||||
"anyOf": [
|
||||
{ "enum": [42] },
|
||||
{ "$ref": "boo" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "boo",
|
||||
"type": "object",
|
||||
"required": ["quux"],
|
||||
"properties": {
|
||||
"quux": { "$ref": "foo#/definitions/bar" }
|
||||
}
|
||||
});
|
||||
|
||||
var validate = ajv.compile({ "$ref": "foo#/definitions/bar" });
|
||||
|
||||
validate({ baz: { quux: { baz: 42 } } }) .should.equal(true);
|
||||
validate({ baz: { quux: { baz: "foo" } } }) .should.equal(false);
|
||||
});
|
||||
|
||||
it('should compile and validate schema when both refs are fragments', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "foo",
|
||||
"definitions": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"baz": {
|
||||
"anyOf": [
|
||||
{ "enum": [42] },
|
||||
{ "$ref": "boo#/definitions/buu" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "boo",
|
||||
"definitions": {
|
||||
"buu": {
|
||||
"type": "object",
|
||||
"required": ["quux"],
|
||||
"properties": {
|
||||
"quux": { "$ref": "foo#/definitions/bar" }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var validate = ajv.compile({ "$ref": "foo#/definitions/bar" });
|
||||
|
||||
validate({ baz: { quux: { baz: 42 } } }) .should.equal(true);
|
||||
validate({ baz: { quux: { baz: "foo" } } }) .should.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #240, mutually recursive fragment refs reference a common schema', function() {
|
||||
var apiSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://api.schema#',
|
||||
resource: {
|
||||
$id: '#resource',
|
||||
properties: {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
},
|
||||
resourceIdentifier: {
|
||||
$id: '#resource_identifier',
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
type: { type: 'string' }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var domainSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://domain.schema#',
|
||||
properties: {
|
||||
data: {
|
||||
oneOf: [
|
||||
{ $ref: 'schema://library.schema#resource_identifier' },
|
||||
{ $ref: 'schema://catalog_item.schema#resource_identifier' },
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
it('should compile and validate schema when one ref is fragment', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
var librarySchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://library.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
catalogItems: {
|
||||
type: 'array',
|
||||
items: { $ref: 'schema://catalog_item_resource_identifier.schema#' }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['Library']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var catalogItemSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://catalog_item.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
library: { $ref: 'schema://library.schema#resource_identifier' }
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['CatalogItem']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var catalogItemResourceIdentifierSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://catalog_item_resource_identifier.schema#',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
enum: ['CatalogItem']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
$ref: 'schema://api.schema#resource_identifier'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
ajv.addSchema(librarySchema);
|
||||
ajv.addSchema(catalogItemSchema);
|
||||
ajv.addSchema(catalogItemResourceIdentifierSchema);
|
||||
ajv.addSchema(apiSchema);
|
||||
|
||||
var validate = ajv.compile(domainSchema);
|
||||
testSchema(validate);
|
||||
});
|
||||
|
||||
it('should compile and validate schema when both refs are fragments', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
var librarySchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://library.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
catalogItems: {
|
||||
type: 'array',
|
||||
items: { $ref: 'schema://catalog_item.schema#resource_identifier' }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['Library']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var catalogItemSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://catalog_item.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
library: { $ref: 'schema://library.schema#resource_identifier' }
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['CatalogItem']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ajv.addSchema(librarySchema);
|
||||
ajv.addSchema(catalogItemSchema);
|
||||
ajv.addSchema(apiSchema);
|
||||
|
||||
var validate = ajv.compile(domainSchema);
|
||||
testSchema(validate);
|
||||
});
|
||||
|
||||
|
||||
function testSchema(validate) {
|
||||
validate({ data: { type: 'Library', id: '123' } }) .should.equal(true);
|
||||
validate({ data: { type: 'Library', id: 123 } }) .should.equal(false);
|
||||
validate({ data: { type: 'CatalogItem', id: '123' } }) .should.equal(true);
|
||||
validate({ data: { type: 'CatalogItem', id: 123 } }) .should.equal(false);
|
||||
validate({ data: { type: 'Foo', id: '123' } }) .should.equal(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
describe('issue #259, support validating [meta-]schemas against themselves', function() {
|
||||
it('should add schema before validation if "id" is the same as "$schema"', function() {
|
||||
var ajv = new Ajv;
|
||||
var hyperSchema = require('./remotes/hyper-schema.json');
|
||||
ajv.addMetaSchema(hyperSchema);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe.skip('issue #273, schemaPath in error in referenced schema', function() {
|
||||
it('should have canonic reference with hash after file name', function() {
|
||||
test(new Ajv);
|
||||
test(new Ajv({inlineRefs: false}));
|
||||
|
||||
function test(ajv) {
|
||||
var schema = {
|
||||
"properties": {
|
||||
"a": { "$ref": "int" }
|
||||
}
|
||||
};
|
||||
|
||||
var referencedSchema = {
|
||||
"id": "int",
|
||||
"type": "integer"
|
||||
};
|
||||
|
||||
ajv.addSchema(referencedSchema);
|
||||
var validate = ajv.compile(schema);
|
||||
|
||||
validate({ "a": "foo" }) .should.equal(false);
|
||||
validate.errors[0].schemaPath .should.equal('int#/type');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #342, support uniqueItems with some non-JSON objects', function() {
|
||||
var validate;
|
||||
|
||||
before(function() {
|
||||
var ajv = new Ajv;
|
||||
validate = ajv.compile({ uniqueItems: true });
|
||||
});
|
||||
|
||||
it('should allow different RegExps', function() {
|
||||
validate([/foo/, /bar/]) .should.equal(true);
|
||||
validate([/foo/ig, /foo/gi]) .should.equal(false);
|
||||
validate([/foo/, {}]) .should.equal(true);
|
||||
});
|
||||
|
||||
it('should allow different Dates', function() {
|
||||
validate([new Date('2016-11-11'), new Date('2016-11-12')]) .should.equal(true);
|
||||
validate([new Date('2016-11-11'), new Date('2016-11-11')]) .should.equal(false);
|
||||
validate([new Date('2016-11-11'), {}]) .should.equal(true);
|
||||
});
|
||||
|
||||
it('should allow undefined properties', function() {
|
||||
validate([{}, {foo: undefined}]) .should.equal(true);
|
||||
validate([{foo: undefined}, {}]) .should.equal(true);
|
||||
validate([{foo: undefined}, {bar: undefined}]) .should.equal(true);
|
||||
validate([{foo: undefined}, {foo: undefined}]) .should.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #388, code clean-up not working', function() {
|
||||
it('should remove assignement to rootData if it is not used', function() {
|
||||
var ajv = new Ajv;
|
||||
var validate = ajv.compile({
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: { type: 'string' }
|
||||
}
|
||||
});
|
||||
var code = validate.toString();
|
||||
code.match(/rootData/g).length .should.equal(1);
|
||||
});
|
||||
|
||||
it('should remove assignement to errors if they are not used', function() {
|
||||
var ajv = new Ajv;
|
||||
var validate = ajv.compile({
|
||||
type: 'object'
|
||||
});
|
||||
var code = validate.toString();
|
||||
should.equal(code.match(/[^.]errors|vErrors/g), null);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #485, order of type validation', function() {
|
||||
it('should validate types befor keywords', function() {
|
||||
var ajv = new Ajv({allErrors: true});
|
||||
var validate = ajv.compile({
|
||||
type: ['integer', 'string'],
|
||||
required: ['foo'],
|
||||
minimum: 2
|
||||
});
|
||||
|
||||
validate(2) .should.equal(true);
|
||||
validate('foo') .should.equal(true);
|
||||
|
||||
validate(1.5) .should.equal(false);
|
||||
checkErrors(['type', 'minimum']);
|
||||
|
||||
validate({}) .should.equal(false);
|
||||
checkErrors(['type', 'required']);
|
||||
|
||||
function checkErrors(expectedErrs) {
|
||||
validate.errors .should.have.length(expectedErrs.length);
|
||||
expectedErrs.forEach(function (keyword, i) {
|
||||
validate.errors[i].keyword .should.equal(keyword);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #521, incorrect warning with "id" property', function() {
|
||||
it('should not log warning', function() {
|
||||
var ajv = new Ajv({schemaId: '$id'});
|
||||
var consoleWarn = console.warn;
|
||||
console.warn = function() {
|
||||
throw new Error('should not log warning');
|
||||
};
|
||||
|
||||
try {
|
||||
ajv.compile({
|
||||
"$id": "http://example.com/schema.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "string"},
|
||||
},
|
||||
"required": [ "id"]
|
||||
});
|
||||
} finally {
|
||||
console.warn = consoleWarn;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #533, throwing missing ref exception with option missingRefs: "ignore"', function() {
|
||||
var schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": {"$ref": "#/definitions/missing"},
|
||||
"bar": {"$ref": "#/definitions/missing"}
|
||||
}
|
||||
};
|
||||
|
||||
it('should pass validation without throwing exception', function() {
|
||||
var ajv = new Ajv({missingRefs: 'ignore'});
|
||||
var validate = ajv.compile(schema);
|
||||
validate({foo: 'anything'}) .should.equal(true);
|
||||
validate({foo: 'anything', bar: 'whatever'}) .should.equal(true);
|
||||
});
|
||||
|
||||
it('should throw exception during schema compilation with option missingRefs: true', function() {
|
||||
var ajv = new Ajv;
|
||||
should.throw(function() {
|
||||
ajv.compile(schema);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('full date format validation should understand leap years', function () {
|
||||
it('should handle non leap year affected dates with date-time', function() {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date-time' };
|
||||
var validDateTime = '2016-01-31T00:00:00Z';
|
||||
|
||||
ajv.validate(schema, validDateTime).should.equal(true);
|
||||
});
|
||||
|
||||
it('should handle non leap year affected dates with date', function () {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date' };
|
||||
var validDate = '2016-11-30';
|
||||
|
||||
ajv.validate(schema, validDate).should.equal(true);
|
||||
});
|
||||
|
||||
it('should handle year leaps as date-time', function() {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date-time' };
|
||||
var validDateTime = '2016-02-29T00:00:00Z';
|
||||
var invalidDateTime = '2017-02-29T00:00:00Z';
|
||||
|
||||
ajv.validate(schema, validDateTime) .should.equal(true);
|
||||
ajv.validate(schema, invalidDateTime) .should.equal(false);
|
||||
});
|
||||
|
||||
it('should handle year leaps as date', function() {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date' };
|
||||
var validDate = '2016-02-29';
|
||||
var invalidDate = '2017-02-29';
|
||||
|
||||
ajv.validate(schema, validDate) .should.equal(true);
|
||||
ajv.validate(schema, invalidDate) .should.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('property __proto__ should be removed with removeAdditional option, issue #743', function() {
|
||||
it('should remove additional properties', function() {
|
||||
var ajv = new Ajv({removeAdditional: true});
|
||||
|
||||
var schema = {
|
||||
properties: {
|
||||
obj: {
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
a: { type: 'string' },
|
||||
b: { type: 'string' },
|
||||
c: { type: 'string' },
|
||||
d: { type: 'string' },
|
||||
e: { type: 'string' },
|
||||
f: { type: 'string' },
|
||||
g: { type: 'string' },
|
||||
h: { type: 'string' },
|
||||
i: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var obj= Object.create(null);
|
||||
obj.__proto__ = null; // should be removed
|
||||
obj.additional = 'will be removed';
|
||||
obj.a = 'valid';
|
||||
obj.b = 'valid';
|
||||
|
||||
var data = {obj: obj};
|
||||
|
||||
ajv.validate(schema, data) .should.equal(true);
|
||||
Object.keys(data.obj) .should.eql(['a', 'b']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('issue #768, fix passContext in recursive $ref', function() {
|
||||
var ajv, contexts;
|
||||
|
||||
beforeEach(function() {
|
||||
contexts = [];
|
||||
});
|
||||
|
||||
describe('passContext = true', function() {
|
||||
it('should pass this value as context to custom keyword validation function', function() {
|
||||
var validate = getValidate(true);
|
||||
var self = {};
|
||||
validate.call(self, { bar: 'a', baz: { bar: 'b' } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(self);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('passContext = false', function() {
|
||||
it('should pass ajv instance as context to custom keyword validation function', function() {
|
||||
var validate = getValidate(false);
|
||||
validate({ bar: 'a', baz: { bar: 'b' } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(ajv);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ref is fragment and passContext = true', function() {
|
||||
it('should pass this value as context to custom keyword validation function', function() {
|
||||
var validate = getValidateFragments(true);
|
||||
var self = {};
|
||||
validate.call(self, { baz: { corge: 'a', quux: { baz: { corge: 'b' } } } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(self);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ref is fragment and passContext = false', function() {
|
||||
it('should pass ajv instance as context to custom keyword validation function', function() {
|
||||
var validate = getValidateFragments(false);
|
||||
validate({ baz: { corge: 'a', quux: { baz: { corge: 'b' } } } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(ajv);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getValidate(passContext) {
|
||||
ajv = new Ajv({ passContext: passContext });
|
||||
ajv.addKeyword('testValidate', { validate: storeContext });
|
||||
|
||||
var schema = {
|
||||
"$id" : "foo",
|
||||
"type": "object",
|
||||
"required": ["bar"],
|
||||
"properties": {
|
||||
"bar": { "testValidate": true },
|
||||
"baz": {
|
||||
"$ref": "foo"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return ajv.compile(schema);
|
||||
}
|
||||
|
||||
|
||||
function getValidateFragments(passContext) {
|
||||
ajv = new Ajv({ passContext: passContext });
|
||||
ajv.addKeyword('testValidate', { validate: storeContext });
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "foo",
|
||||
"definitions": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"baz": {
|
||||
"$ref": "boo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "boo",
|
||||
"type": "object",
|
||||
"required": ["corge"],
|
||||
"properties": {
|
||||
"quux": { "$ref": "foo#/definitions/bar" },
|
||||
"corge": { "testValidate": true }
|
||||
}
|
||||
});
|
||||
|
||||
return ajv.compile({ "$ref": "foo#/definitions/bar" });
|
||||
}
|
||||
|
||||
function storeContext() {
|
||||
contexts.push(this);
|
||||
return true;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,58 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #181, custom keyword is not validated in allErrors mode if there were previous error', function() {
|
||||
it('should validate custom keyword that doesn\'t create errors', function() {
|
||||
testCustomKeywordErrors({
|
||||
type:'object',
|
||||
errors: true,
|
||||
validate: function v(/* value */) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should validate custom keyword that creates errors', function() {
|
||||
testCustomKeywordErrors({
|
||||
type:'object',
|
||||
errors: true,
|
||||
validate: function v(/* value */) {
|
||||
v.errors = v.errors || [];
|
||||
v.errors.push({
|
||||
keyword: 'alwaysFails',
|
||||
message: 'alwaysFails error',
|
||||
params: {
|
||||
keyword: 'alwaysFails'
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function testCustomKeywordErrors(def) {
|
||||
var ajv = new Ajv({ allErrors: true });
|
||||
|
||||
ajv.addKeyword('alwaysFails', def);
|
||||
|
||||
var schema = {
|
||||
required: ['foo'],
|
||||
alwaysFails: true
|
||||
};
|
||||
|
||||
var validate = ajv.compile(schema);
|
||||
|
||||
validate({ foo: 1 }) .should.equal(false);
|
||||
validate.errors .should.have.length(1);
|
||||
validate.errors[0].keyword .should.equal('alwaysFails');
|
||||
|
||||
validate({}) .should.equal(false);
|
||||
validate.errors .should.have.length(2);
|
||||
validate.errors[0].keyword .should.equal('required');
|
||||
validate.errors[1].keyword .should.equal('alwaysFails');
|
||||
}
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #182, NaN validation', function() {
|
||||
it('should not pass minimum/maximum validation', function() {
|
||||
testNaN({ minimum: 1 }, false);
|
||||
testNaN({ maximum: 1 }, false);
|
||||
});
|
||||
|
||||
it('should pass type: number validation', function() {
|
||||
testNaN({ type: 'number' }, true);
|
||||
});
|
||||
|
||||
it('should not pass type: integer validation', function() {
|
||||
testNaN({ type: 'integer' }, false);
|
||||
});
|
||||
|
||||
function testNaN(schema, NaNisValid) {
|
||||
var ajv = new Ajv;
|
||||
var validate = ajv.compile(schema);
|
||||
validate(NaN) .should.equal(NaNisValid);
|
||||
}
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #204, options schemas and $data used together', function() {
|
||||
it('should use v5 metaschemas by default', function() {
|
||||
var ajv = new Ajv({
|
||||
schemas: [{$id: 'str', type: 'string'}],
|
||||
$data: true
|
||||
});
|
||||
|
||||
var schema = { const: 42 };
|
||||
var validate = ajv.compile(schema);
|
||||
|
||||
validate(42) .should.equal(true);
|
||||
validate(43) .should.equal(false);
|
||||
|
||||
ajv.validate('str', 'foo') .should.equal(true);
|
||||
ajv.validate('str', 42) .should.equal(false);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,79 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #210, mutual recursive $refs that are schema fragments', function() {
|
||||
it('should compile and validate schema when one ref is fragment', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "foo",
|
||||
"definitions": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"baz": {
|
||||
"anyOf": [
|
||||
{ "enum": [42] },
|
||||
{ "$ref": "boo" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "boo",
|
||||
"type": "object",
|
||||
"required": ["quux"],
|
||||
"properties": {
|
||||
"quux": { "$ref": "foo#/definitions/bar" }
|
||||
}
|
||||
});
|
||||
|
||||
var validate = ajv.compile({ "$ref": "foo#/definitions/bar" });
|
||||
|
||||
validate({ baz: { quux: { baz: 42 } } }) .should.equal(true);
|
||||
validate({ baz: { quux: { baz: "foo" } } }) .should.equal(false);
|
||||
});
|
||||
|
||||
it('should compile and validate schema when both refs are fragments', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "foo",
|
||||
"definitions": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"baz": {
|
||||
"anyOf": [
|
||||
{ "enum": [42] },
|
||||
{ "$ref": "boo#/definitions/buu" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "boo",
|
||||
"definitions": {
|
||||
"buu": {
|
||||
"type": "object",
|
||||
"required": ["quux"],
|
||||
"properties": {
|
||||
"quux": { "$ref": "foo#/definitions/bar" }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var validate = ajv.compile({ "$ref": "foo#/definitions/bar" });
|
||||
|
||||
validate({ baz: { quux: { baz: 42 } } }) .should.equal(true);
|
||||
validate({ baz: { quux: { baz: "foo" } } }) .should.equal(false);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,210 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #240, mutually recursive fragment refs reference a common schema', function() {
|
||||
var apiSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://api.schema#',
|
||||
resource: {
|
||||
$id: '#resource',
|
||||
properties: {
|
||||
id: { type: 'string' }
|
||||
}
|
||||
},
|
||||
resourceIdentifier: {
|
||||
$id: '#resource_identifier',
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
type: { type: 'string' }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var domainSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://domain.schema#',
|
||||
properties: {
|
||||
data: {
|
||||
oneOf: [
|
||||
{ $ref: 'schema://library.schema#resource_identifier' },
|
||||
{ $ref: 'schema://catalog_item.schema#resource_identifier' },
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
it('should compile and validate schema when one ref is fragment', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
var librarySchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://library.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
catalogItems: {
|
||||
type: 'array',
|
||||
items: { $ref: 'schema://catalog_item_resource_identifier.schema#' }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['Library']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var catalogItemSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://catalog_item.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
library: { $ref: 'schema://library.schema#resource_identifier' }
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['CatalogItem']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var catalogItemResourceIdentifierSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://catalog_item_resource_identifier.schema#',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
enum: ['CatalogItem']
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
$ref: 'schema://api.schema#resource_identifier'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
ajv.addSchema(librarySchema);
|
||||
ajv.addSchema(catalogItemSchema);
|
||||
ajv.addSchema(catalogItemResourceIdentifierSchema);
|
||||
ajv.addSchema(apiSchema);
|
||||
|
||||
var validate = ajv.compile(domainSchema);
|
||||
testSchema(validate);
|
||||
});
|
||||
|
||||
it('should compile and validate schema when both refs are fragments', function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
var librarySchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://library.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
catalogItems: {
|
||||
type: 'array',
|
||||
items: { $ref: 'schema://catalog_item.schema#resource_identifier' }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['Library']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var catalogItemSchema = {
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
$id: 'schema://catalog_item.schema#',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
links: {
|
||||
properties: {
|
||||
library: { $ref: 'schema://library.schema#resource_identifier' }
|
||||
}
|
||||
}
|
||||
},
|
||||
definitions: {
|
||||
resource_identifier: {
|
||||
$id: '#resource_identifier',
|
||||
allOf: [
|
||||
{
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
'enum': ['CatalogItem']
|
||||
}
|
||||
}
|
||||
},
|
||||
{ $ref: 'schema://api.schema#resource_identifier' }
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ajv.addSchema(librarySchema);
|
||||
ajv.addSchema(catalogItemSchema);
|
||||
ajv.addSchema(apiSchema);
|
||||
|
||||
var validate = ajv.compile(domainSchema);
|
||||
testSchema(validate);
|
||||
});
|
||||
|
||||
|
||||
function testSchema(validate) {
|
||||
validate({ data: { type: 'Library', id: '123' } }) .should.equal(true);
|
||||
validate({ data: { type: 'Library', id: 123 } }) .should.equal(false);
|
||||
validate({ data: { type: 'CatalogItem', id: '123' } }) .should.equal(true);
|
||||
validate({ data: { type: 'CatalogItem', id: 123 } }) .should.equal(false);
|
||||
validate({ data: { type: 'Foo', id: '123' } }) .should.equal(false);
|
||||
}
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #259, support validating [meta-]schemas against themselves', function() {
|
||||
it('should add schema before validation if "id" is the same as "$schema"', function() {
|
||||
var ajv = new Ajv;
|
||||
var hyperSchema = require('../remotes/hyper-schema.json');
|
||||
ajv.addMetaSchema(hyperSchema);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe.skip('issue #273, schemaPath in error in referenced schema', function() {
|
||||
it('should have canonic reference with hash after file name', function() {
|
||||
test(new Ajv);
|
||||
test(new Ajv({inlineRefs: false}));
|
||||
|
||||
function test(ajv) {
|
||||
var schema = {
|
||||
"properties": {
|
||||
"a": { "$ref": "int" }
|
||||
}
|
||||
};
|
||||
|
||||
var referencedSchema = {
|
||||
"id": "int",
|
||||
"type": "integer"
|
||||
};
|
||||
|
||||
ajv.addSchema(referencedSchema);
|
||||
var validate = ajv.compile(schema);
|
||||
|
||||
validate({ "a": "foo" }) .should.equal(false);
|
||||
validate.errors[0].schemaPath .should.equal('int#/type');
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #342, support uniqueItems with some non-JSON objects', function() {
|
||||
var validate;
|
||||
|
||||
before(function() {
|
||||
var ajv = new Ajv;
|
||||
validate = ajv.compile({ uniqueItems: true });
|
||||
});
|
||||
|
||||
it('should allow different RegExps', function() {
|
||||
validate([/foo/, /bar/]) .should.equal(true);
|
||||
validate([/foo/ig, /foo/gi]) .should.equal(false);
|
||||
validate([/foo/, {}]) .should.equal(true);
|
||||
});
|
||||
|
||||
it('should allow different Dates', function() {
|
||||
validate([new Date('2016-11-11'), new Date('2016-11-12')]) .should.equal(true);
|
||||
validate([new Date('2016-11-11'), new Date('2016-11-11')]) .should.equal(false);
|
||||
validate([new Date('2016-11-11'), {}]) .should.equal(true);
|
||||
});
|
||||
|
||||
it('should allow undefined properties', function() {
|
||||
validate([{}, {foo: undefined}]) .should.equal(true);
|
||||
validate([{foo: undefined}, {}]) .should.equal(true);
|
||||
validate([{foo: undefined}, {bar: undefined}]) .should.equal(true);
|
||||
validate([{foo: undefined}, {foo: undefined}]) .should.equal(false);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
var should = require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #388, code clean-up not working', function() {
|
||||
it('should remove assignement to rootData if it is not used', function() {
|
||||
var ajv = new Ajv;
|
||||
var validate = ajv.compile({
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: { type: 'string' }
|
||||
}
|
||||
});
|
||||
var code = validate.toString();
|
||||
code.match(/rootData/g).length .should.equal(1);
|
||||
});
|
||||
|
||||
it('should remove assignement to errors if they are not used', function() {
|
||||
var ajv = new Ajv;
|
||||
var validate = ajv.compile({
|
||||
type: 'object'
|
||||
});
|
||||
var code = validate.toString();
|
||||
should.equal(code.match(/[^.]errors|vErrors/g), null);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #485, order of type validation', function() {
|
||||
it('should validate types before keywords', function() {
|
||||
var ajv = new Ajv({allErrors: true});
|
||||
var validate = ajv.compile({
|
||||
type: ['integer', 'string'],
|
||||
required: ['foo'],
|
||||
minimum: 2
|
||||
});
|
||||
|
||||
validate(2) .should.equal(true);
|
||||
validate('foo') .should.equal(true);
|
||||
|
||||
validate(1.5) .should.equal(false);
|
||||
checkErrors(['type', 'minimum']);
|
||||
|
||||
validate({}) .should.equal(false);
|
||||
checkErrors(['type', 'required']);
|
||||
|
||||
function checkErrors(expectedErrs) {
|
||||
validate.errors .should.have.length(expectedErrs.length);
|
||||
expectedErrs.forEach(function (keyword, i) {
|
||||
validate.errors[i].keyword .should.equal(keyword);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
var should = require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #50: references with "definitions"', function () {
|
||||
it('should be supported by addSchema', spec('addSchema'));
|
||||
|
||||
it('should be supported by compile', spec('addSchema'));
|
||||
|
||||
function spec(method) {
|
||||
return function() {
|
||||
var result;
|
||||
|
||||
var ajv = new Ajv;
|
||||
|
||||
ajv[method]({
|
||||
$id: 'http://example.com/test/person.json#',
|
||||
definitions: {
|
||||
name: { type: 'string' }
|
||||
},
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { $ref: '#/definitions/name'}
|
||||
}
|
||||
});
|
||||
|
||||
ajv[method]({
|
||||
$id: 'http://example.com/test/employee.json#',
|
||||
type: 'object',
|
||||
properties: {
|
||||
person: { $ref: '/test/person.json#' },
|
||||
role: { type: 'string' }
|
||||
}
|
||||
});
|
||||
|
||||
result = ajv.validate('http://example.com/test/employee.json#', {
|
||||
person: {
|
||||
name: 'Alice'
|
||||
},
|
||||
role: 'Programmer'
|
||||
});
|
||||
|
||||
result. should.equal(true);
|
||||
should.equal(ajv.errors, null);
|
||||
};
|
||||
}
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #521, incorrect warning with "id" property', function() {
|
||||
it('should not log warning', function() {
|
||||
var ajv = new Ajv({schemaId: '$id'});
|
||||
var consoleWarn = console.warn;
|
||||
console.warn = function() {
|
||||
throw new Error('should not log warning');
|
||||
};
|
||||
|
||||
try {
|
||||
ajv.compile({
|
||||
"$id": "http://example.com/schema.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "string"},
|
||||
},
|
||||
"required": [ "id"]
|
||||
});
|
||||
} finally {
|
||||
console.warn = consoleWarn;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
var should = require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #533, throwing missing ref exception with option missingRefs: "ignore"', function() {
|
||||
var schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": {"$ref": "#/definitions/missing"},
|
||||
"bar": {"$ref": "#/definitions/missing"}
|
||||
}
|
||||
};
|
||||
|
||||
it('should pass validation without throwing exception', function() {
|
||||
var ajv = new Ajv({missingRefs: 'ignore'});
|
||||
var validate = ajv.compile(schema);
|
||||
validate({foo: 'anything'}) .should.equal(true);
|
||||
validate({foo: 'anything', bar: 'whatever'}) .should.equal(true);
|
||||
});
|
||||
|
||||
it('should throw exception during schema compilation with option missingRefs: true', function() {
|
||||
var ajv = new Ajv;
|
||||
should.throw(function() {
|
||||
ajv.compile(schema);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('PR #617, full date format validation should understand leap years', function () {
|
||||
it('should handle non leap year affected dates with date-time', function() {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date-time' };
|
||||
var validDateTime = '2016-01-31T00:00:00Z';
|
||||
|
||||
ajv.validate(schema, validDateTime).should.equal(true);
|
||||
});
|
||||
|
||||
it('should handle non leap year affected dates with date', function () {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date' };
|
||||
var validDate = '2016-11-30';
|
||||
|
||||
ajv.validate(schema, validDate).should.equal(true);
|
||||
});
|
||||
|
||||
it('should handle year leaps as date-time', function() {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date-time' };
|
||||
var validDateTime = '2016-02-29T00:00:00Z';
|
||||
var invalidDateTime = '2017-02-29T00:00:00Z';
|
||||
|
||||
ajv.validate(schema, validDateTime) .should.equal(true);
|
||||
ajv.validate(schema, invalidDateTime) .should.equal(false);
|
||||
});
|
||||
|
||||
it('should handle year leaps as date', function() {
|
||||
var ajv = new Ajv({ format: 'full' });
|
||||
|
||||
var schema = { format: 'date' };
|
||||
var validDate = '2016-02-29';
|
||||
var invalidDate = '2017-02-29';
|
||||
|
||||
ajv.validate(schema, validDate) .should.equal(true);
|
||||
ajv.validate(schema, invalidDate) .should.equal(false);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #743, property __proto__ should be removed with removeAdditional option', function() {
|
||||
it('should remove additional properties', function() {
|
||||
var ajv = new Ajv({removeAdditional: true});
|
||||
|
||||
var schema = {
|
||||
properties: {
|
||||
obj: {
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
a: { type: 'string' },
|
||||
b: { type: 'string' },
|
||||
c: { type: 'string' },
|
||||
d: { type: 'string' },
|
||||
e: { type: 'string' },
|
||||
f: { type: 'string' },
|
||||
g: { type: 'string' },
|
||||
h: { type: 'string' },
|
||||
i: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var obj= Object.create(null);
|
||||
obj.__proto__ = null; // should be removed
|
||||
obj.additional = 'will be removed';
|
||||
obj.a = 'valid';
|
||||
obj.b = 'valid';
|
||||
|
||||
var data = {obj: obj};
|
||||
|
||||
ajv.validate(schema, data) .should.equal(true);
|
||||
Object.keys(data.obj) .should.eql(['a', 'b']);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,114 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #768, fix passContext in recursive $ref', function() {
|
||||
var ajv, contexts;
|
||||
|
||||
beforeEach(function() {
|
||||
contexts = [];
|
||||
});
|
||||
|
||||
describe('passContext = true', function() {
|
||||
it('should pass this value as context to custom keyword validation function', function() {
|
||||
var validate = getValidate(true);
|
||||
var self = {};
|
||||
validate.call(self, { bar: 'a', baz: { bar: 'b' } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(self);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('passContext = false', function() {
|
||||
it('should pass ajv instance as context to custom keyword validation function', function() {
|
||||
var validate = getValidate(false);
|
||||
validate({ bar: 'a', baz: { bar: 'b' } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(ajv);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ref is fragment and passContext = true', function() {
|
||||
it('should pass this value as context to custom keyword validation function', function() {
|
||||
var validate = getValidateFragments(true);
|
||||
var self = {};
|
||||
validate.call(self, { baz: { corge: 'a', quux: { baz: { corge: 'b' } } } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(self);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('ref is fragment and passContext = false', function() {
|
||||
it('should pass ajv instance as context to custom keyword validation function', function() {
|
||||
var validate = getValidateFragments(false);
|
||||
validate({ baz: { corge: 'a', quux: { baz: { corge: 'b' } } } });
|
||||
contexts .should.have.length(2);
|
||||
contexts.forEach(function(ctx) {
|
||||
ctx .should.equal(ajv);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getValidate(passContext) {
|
||||
ajv = new Ajv({ passContext: passContext });
|
||||
ajv.addKeyword('testValidate', { validate: storeContext });
|
||||
|
||||
var schema = {
|
||||
"$id" : "foo",
|
||||
"type": "object",
|
||||
"required": ["bar"],
|
||||
"properties": {
|
||||
"bar": { "testValidate": true },
|
||||
"baz": {
|
||||
"$ref": "foo"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return ajv.compile(schema);
|
||||
}
|
||||
|
||||
|
||||
function getValidateFragments(passContext) {
|
||||
ajv = new Ajv({ passContext: passContext });
|
||||
ajv.addKeyword('testValidate', { validate: storeContext });
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "foo",
|
||||
"definitions": {
|
||||
"bar": {
|
||||
"properties": {
|
||||
"baz": {
|
||||
"$ref": "boo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ajv.addSchema({
|
||||
"$id" : "boo",
|
||||
"type": "object",
|
||||
"required": ["corge"],
|
||||
"properties": {
|
||||
"quux": { "$ref": "foo#/definitions/bar" },
|
||||
"corge": { "testValidate": true }
|
||||
}
|
||||
});
|
||||
|
||||
return ajv.compile({ "$ref": "foo#/definitions/bar" });
|
||||
}
|
||||
|
||||
function storeContext() {
|
||||
contexts.push(this);
|
||||
return true;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('../ajv');
|
||||
require('../chai').should();
|
||||
|
||||
|
||||
describe('issue #8: schema with shared references', function() {
|
||||
it('should be supported by addSchema', spec('addSchema'));
|
||||
|
||||
it('should be supported by compile', spec('compile'));
|
||||
|
||||
function spec(method) {
|
||||
return function() {
|
||||
var ajv = new Ajv;
|
||||
|
||||
var propertySchema = {
|
||||
type: 'string',
|
||||
maxLength: 4
|
||||
};
|
||||
|
||||
var schema = {
|
||||
$id: 'obj.json#',
|
||||
type: 'object',
|
||||
properties: {
|
||||
foo: propertySchema,
|
||||
bar: propertySchema
|
||||
}
|
||||
};
|
||||
|
||||
ajv[method](schema);
|
||||
|
||||
var result = ajv.validate('obj.json#', { foo: 'abc', bar: 'def' });
|
||||
result .should.equal(true);
|
||||
|
||||
result = ajv.validate('obj.json#', { foo: 'abcde', bar: 'fghg' });
|
||||
result .should.equal(false);
|
||||
ajv.errors .should.have.length(1);
|
||||
};
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue