Skip to content

Commit

Permalink
Merge pull request #771 from cvlab/master
Browse files Browse the repository at this point in the history
passContext in recursive $ref
  • Loading branch information
epoberezkin authored May 8, 2018
2 parents 911555f + 5ebfe2c commit 40bd2da
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 2 deletions.
4 changes: 3 additions & 1 deletion lib/ajv.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,11 @@ function _compile(schemaObj, root) {
return v;


/* @this {*} - custom context, see passContext option */
function callValidate() {
/* jshint validthis: true */
var _validate = schemaObj.validate;
var result = _validate.apply(null, arguments);
var result = _validate.apply(this, arguments);
callValidate.errors = _validate.errors;
return result;
}
Expand Down
4 changes: 3 additions & 1 deletion lib/compile/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ function compile(schema, root, localRefs, baseId) {
endCompiling.call(this, schema, root, baseId);
}

/* @this {*} - custom context, see passContext option */
function callValidate() {
/* jshint validthis: true */
var validate = compilation.validate;
var result = validate.apply(null, arguments);
var result = validate.apply(this, arguments);
callValidate.errors = validate.errors;
return result;
}
Expand Down
110 changes: 110 additions & 0 deletions spec/issues.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -703,3 +703,113 @@ describe('property __proto__ should be removed with removeAdditional option, iss
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 comments on commit 40bd2da

Please # to comment.